Thread

  1. [PATCH v1 1/5] WIP: Rename attnum to attphysnum

    Julien Rouhaud <julien.rouhaud@free.fr> — 2022-06-03T17:50:14Z

    This is the bare minimum to make the code compile, a lot more effort is
    required for a proper patch.
    
    A lot of things would need to be renamed accordingly, for instance
    attnameAttNum() and similar, and a lot of variables name attnums, pk_attnums
    and so on.
    
    Author: Julien Rouhaud
    Reviewed-by: FIXME
    Discussion: FIXME
    ---
     contrib/amcheck/amcheck--1.2--1.3.sql         |   2 +-
     contrib/amcheck/expected/check_heap.out       |  92 ++---
     contrib/amcheck/verify_heapam.c               |  30 +-
     contrib/amcheck/verify_nbtree.c               |   2 +-
     contrib/dblink/dblink.c                       |  14 +-
     contrib/file_fdw/file_fdw.c                   |  22 +-
     contrib/lo/lo.c                               |  14 +-
     contrib/pageinspect/expected/brin.out         |   8 +-
     contrib/pageinspect/pageinspect--1.2--1.3.sql |   2 +-
     contrib/pageinspect/pageinspect--1.5.sql      |   2 +-
     contrib/pageinspect/pageinspect--1.8--1.9.sql |   2 +-
     contrib/pageinspect/sql/brin.sql              |   2 +-
     contrib/postgres_fdw/deparse.c                |  22 +-
     contrib/postgres_fdw/postgres_fdw.c           |  38 +-
     contrib/sepgsql/dml.c                         |  10 +-
     contrib/sepgsql/label.c                       |   2 +-
     contrib/sepgsql/relation.c                    |  32 +-
     contrib/sepgsql/sepgsql.h                     |   8 +-
     contrib/spi/autoinc.c                         |  10 +-
     contrib/spi/insert_username.c                 |  10 +-
     contrib/spi/moddatetime.c                     |  10 +-
     contrib/test_decoding/test_decoding.c         |   2 +-
     contrib/vacuumlo/vacuumlo.c                   |   2 +-
     doc/src/sgml/amcheck.sgml                     |   4 +-
     doc/src/sgml/fdwhandler.sgml                  |   2 +-
     doc/src/sgml/pageinspect.sgml                 |   4 +-
     doc/src/sgml/ref/psql-ref.sgml                |   2 +-
     doc/src/sgml/sources.sgml                     |   2 +-
     doc/src/sgml/trigger.sgml                     |   2 +-
     doc/src/sgml/xaggr.sgml                       |   4 +-
     src/backend/access/brin/brin_tuple.c          |  18 +-
     src/backend/access/common/attmap.c            |   2 +-
     src/backend/access/common/heaptuple.c         | 108 +++---
     src/backend/access/common/indextuple.c        |  36 +-
     src/backend/access/common/printsimple.c       |   2 +-
     src/backend/access/common/tupdesc.c           |  30 +-
     src/backend/access/gin/ginbulk.c              |  24 +-
     src/backend/access/gin/ginentrypage.c         |  30 +-
     src/backend/access/gin/ginfast.c              |  18 +-
     src/backend/access/gin/ginget.c               |  42 +--
     src/backend/access/gin/gininsert.c            |  46 +--
     src/backend/access/gin/ginlogic.c             |  10 +-
     src/backend/access/gin/ginscan.c              |  22 +-
     src/backend/access/gin/ginutil.c              |  16 +-
     src/backend/access/gin/ginvacuum.c            |   6 +-
     src/backend/access/index/genam.c              |   8 +-
     src/backend/access/index/indexam.c            |  20 +-
     src/backend/access/nbtree/nbtutils.c          |  14 +-
     src/backend/bootstrap/bootstrap.c             |  78 ++--
     src/backend/catalog/aclchk.c                  |  70 ++--
     src/backend/catalog/catalog.c                 |   2 +-
     src/backend/catalog/genbki.pl                 |  20 +-
     src/backend/catalog/heap.c                    |  76 ++--
     src/backend/catalog/index.c                   |  18 +-
     src/backend/catalog/indexing.c                |   6 +-
     src/backend/catalog/information_schema.sql    |  68 ++--
     src/backend/catalog/objectaddress.c           |  24 +-
     src/backend/catalog/pg_attrdef.c              |  32 +-
     src/backend/catalog/pg_depend.c               |  12 +-
     src/backend/catalog/pg_publication.c          |  14 +-
     src/backend/catalog/system_views.sql          |  18 +-
     src/backend/commands/analyze.c                |  28 +-
     src/backend/commands/copy.c                   |  12 +-
     src/backend/commands/copyfrom.c               |  42 +--
     src/backend/commands/copyfromparse.c          |  12 +-
     src/backend/commands/copyto.c                 |  46 +--
     src/backend/commands/createas.c               |   6 +-
     src/backend/commands/event_trigger.c          |  14 +-
     src/backend/commands/indexcmds.c              |   2 +-
     src/backend/commands/matview.c                |  12 +-
     src/backend/commands/publicationcmds.c        |  22 +-
     src/backend/commands/sequence.c               |  10 +-
     src/backend/commands/statscmds.c              |   8 +-
     src/backend/commands/tablecmds.c              | 342 +++++++++---------
     src/backend/commands/trigger.c                |  10 +-
     src/backend/commands/tsearchcmds.c            |  16 +-
     src/backend/commands/typecmds.c               |  16 +-
     src/backend/executor/execExpr.c               |  52 +--
     src/backend/executor/execExprInterp.c         | 110 +++---
     src/backend/executor/execMain.c               |   4 +-
     src/backend/executor/execPartition.c          |   6 +-
     src/backend/executor/execTuples.c             |  52 +--
     src/backend/executor/execUtils.c              |   2 +-
     src/backend/executor/nodeAgg.c                |  12 +-
     src/backend/executor/spi.c                    |  14 +-
     src/backend/foreign/foreign.c                 |  10 +-
     src/backend/jit/llvm/llvmjit_deform.c         | 104 +++---
     src/backend/jit/llvm/llvmjit_expr.c           |   4 +-
     src/backend/optimizer/util/appendinfo.c       |   2 +-
     src/backend/parser/analyze.c                  |   6 +-
     src/backend/parser/parse_clause.c             |  16 +-
     src/backend/parser/parse_relation.c           | 122 +++----
     src/backend/parser/parse_target.c             |  52 +--
     src/backend/parser/parse_type.c               |   8 +-
     src/backend/parser/parse_utilcmd.c            |  64 ++--
     src/backend/replication/basebackup_copy.c     |   6 +-
     src/backend/replication/logical/proto.c       |  14 +-
     src/backend/replication/logical/relation.c    |  20 +-
     .../replication/logical/reorderbuffer.c       |   2 +-
     src/backend/replication/logical/tablesync.c   |  14 +-
     src/backend/replication/logical/worker.c      |  20 +-
     src/backend/replication/pgoutput/pgoutput.c   |   2 +-
     src/backend/replication/walsender.c           |   4 +-
     src/backend/statistics/dependencies.c         | 116 +++---
     src/backend/statistics/extended_stats.c       |  40 +-
     src/backend/statistics/mvdistinct.c           |   4 +-
     src/backend/utils/adt/acl.c                   |  34 +-
     src/backend/utils/adt/expandedrecord.c        |   4 +-
     src/backend/utils/adt/misc.c                  |   6 +-
     src/backend/utils/adt/ri_triggers.c           |   6 +-
     src/backend/utils/adt/ruleutils.c             |  90 ++---
     src/backend/utils/adt/selfuncs.c              |  60 +--
     src/backend/utils/cache/attoptcache.c         |  16 +-
     src/backend/utils/cache/catcache.c            |  10 +-
     src/backend/utils/cache/lsyscache.c           |  58 +--
     src/backend/utils/cache/relcache.c            |  42 +--
     src/backend/utils/cache/syscache.c            |  18 +-
     src/bin/initdb/initdb.c                       |   2 +-
     src/bin/pg_amcheck/pg_amcheck.c               |   4 +-
     src/bin/pg_amcheck/t/003_check.pl             |   2 +-
     src/bin/pg_dump/pg_dump.c                     |  26 +-
     src/bin/psql/describe.c                       | 158 ++++++--
     src/bin/psql/tab-complete.c                   |   4 +-
     src/include/access/genam.h                    |   6 +-
     src/include/access/gin_private.h              |  24 +-
     src/include/access/htup_details.h             |  36 +-
     src/include/access/itup.h                     |  18 +-
     src/include/bootstrap/bootstrap.h             |   2 +-
     src/include/catalog/dependency.h              |   2 +-
     src/include/catalog/heap.h                    |   8 +-
     src/include/catalog/pg_attrdef.h              |  10 +-
     src/include/catalog/pg_attribute.h            |   8 +-
     src/include/catalog/pg_constraint.h           |   4 +-
     src/include/catalog/pg_index.h                |   2 +-
     src/include/catalog/pg_partitioned_table.h    |   2 +-
     src/include/catalog/pg_statistic.h            |   2 +-
     src/include/catalog/pg_statistic_ext.h        |   2 +-
     src/include/catalog/pg_trigger.h              |   2 +-
     src/include/executor/execExpr.h               |   6 +-
     src/include/executor/spi.h                    |   2 +-
     src/include/executor/tuptable.h               |  42 +--
     src/include/foreign/foreign.h                 |   2 +-
     src/include/parser/parsetree.h                |   4 +-
     src/include/utils/acl.h                       |   8 +-
     src/include/utils/attoptcache.h               |   2 +-
     src/include/utils/lsyscache.h                 |  18 +-
     src/include/utils/relcache.h                  |   2 +-
     src/include/utils/selfuncs.h                  |   2 +-
     src/include/utils/syscache.h                  |   6 +-
     src/pl/plpgsql/src/plpgsql.h                  |   2 +-
     ...summarization-and-inprogress-insertion.out |  28 +-
     .../test_misc/t/001_constraint_validation.pl  |   2 +-
     src/test/regress/expected/alter_table.out     |  32 +-
     src/test/regress/expected/create_index.out    |  14 +-
     src/test/regress/expected/create_table.out    |   4 +-
     src/test/regress/expected/create_type.out     |   2 +-
     src/test/regress/expected/foreign_key.out     |   2 +-
     src/test/regress/expected/indexing.out        |  48 +--
     src/test/regress/expected/inherit.out         |   2 +-
     src/test/regress/expected/insert.out          |  14 +-
     src/test/regress/expected/join.out            |   4 +-
     src/test/regress/expected/oidjoins.out        |  16 +-
     src/test/regress/expected/opr_sanity.out      |   4 +-
     src/test/regress/expected/psql.out            |   4 +-
     src/test/regress/expected/rules.out           |  18 +-
     src/test/regress/expected/sanity_check.out    |   6 +-
     src/test/regress/expected/type_sanity.out     |  10 +-
     src/test/regress/regress.c                    |  30 +-
     src/test/regress/sql/alter_table.sql          |  22 +-
     src/test/regress/sql/create_index.sql         |   4 +-
     src/test/regress/sql/create_table.sql         |   4 +-
     src/test/regress/sql/create_type.sql          |   2 +-
     src/test/regress/sql/foreign_key.sql          |   2 +-
     src/test/regress/sql/indexing.sql             |  12 +-
     src/test/regress/sql/inherit.sql              |   2 +-
     src/test/regress/sql/insert.sql               |   4 +-
     src/test/regress/sql/join.sql                 |   4 +-
     src/test/regress/sql/opr_sanity.sql           |   4 +-
     src/test/regress/sql/psql.sql                 |   4 +-
     src/test/regress/sql/sanity_check.sql         |   6 +-
     src/test/regress/sql/type_sanity.sql          |  10 +-
     src/tutorial/syscat.source                    |   4 +-
     182 files changed, 1959 insertions(+), 1857 deletions(-)
    
    diff --git a/contrib/amcheck/amcheck--1.2--1.3.sql b/contrib/amcheck/amcheck--1.2--1.3.sql
    index 7237ab738c..5c49ddde17 100644
    --- a/contrib/amcheck/amcheck--1.2--1.3.sql
    +++ b/contrib/amcheck/amcheck--1.2--1.3.sql
    @@ -14,7 +14,7 @@ CREATE FUNCTION verify_heapam(relation regclass,
     							  endblock bigint default null,
     							  blkno OUT bigint,
     							  offnum OUT integer,
    -							  attnum OUT integer,
    +							  attphysnum OUT integer,
     							  msg OUT text)
     RETURNS SETOF record
     AS 'MODULE_PATHNAME', 'verify_heapam'
    diff --git a/contrib/amcheck/expected/check_heap.out b/contrib/amcheck/expected/check_heap.out
    index c010361025..d8267d0578 100644
    --- a/contrib/amcheck/expected/check_heap.out
    +++ b/contrib/amcheck/expected/check_heap.out
    @@ -6,60 +6,60 @@ ERROR:  invalid skip option
     HINT:  Valid skip options are "all-visible", "all-frozen", and "none".
     -- Check specifying invalid block ranges when verifying an empty table
     SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock := 0);
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 5, endblock := 8);
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     -- Check that valid options are not rejected nor corruption reported
     -- for an empty table, and that skip enum-like parameter is case-insensitive
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'none');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-frozen');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-visible');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'None');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'All-Frozen');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'All-Visible');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'NONE');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'ALL-FROZEN');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'ALL-VISIBLE');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     -- Add some data so subsequent tests are not entirely trivial
    @@ -69,23 +69,23 @@ INSERT INTO heaptest (a, b)
     -- Check that valid options are not rejected nor corruption reported
     -- for a non-empty table
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'none');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-frozen');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-visible');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock := 0);
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     CREATE ROLE regress_heaptest_role;
    @@ -98,8 +98,8 @@ GRANT EXECUTE ON FUNCTION verify_heapam(regclass, boolean, boolean, text, bigint
     -- verify permissions are now sufficient
     SET ROLE regress_heaptest_role;
     SELECT * FROM verify_heapam(relation := 'heaptest');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     RESET ROLE;
    @@ -113,23 +113,23 @@ VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) heaptest;
     -- Check that valid options are not rejected nor corruption reported
     -- for a non-empty frozen table
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'none');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-frozen');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-visible');
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock := 0);
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     -- Check that partitioned tables (the parent ones) which don't have visibility
    @@ -147,8 +147,8 @@ CREATE TABLE test_partition partition OF test_partitioned FOR VALUES IN (1);
     SELECT * FROM verify_heapam('test_partition',
     							startblock := NULL,
     							endblock := NULL);
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     -- Check that valid options are not rejected nor corruption reported
    @@ -157,8 +157,8 @@ INSERT INTO test_partitioned (a) (SELECT 1 FROM generate_series(1,1000) gs);
     SELECT * FROM verify_heapam('test_partition',
     							startblock := NULL,
     							endblock := NULL);
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     -- Check that indexes are rejected
    @@ -180,8 +180,8 @@ CREATE SEQUENCE test_sequence;
     SELECT * FROM verify_heapam('test_sequence',
     							startblock := NULL,
     							endblock := NULL);
    - blkno | offnum | attnum | msg 
    --------+--------+--------+-----
    + blkno | offnum | attphysnum | msg 
    +-------+--------+------------+-----
     (0 rows)
     
     -- Check that foreign tables are rejected
    diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
    index e488f5e234..89d69ab394 100644
    --- a/contrib/amcheck/verify_heapam.c
    +++ b/contrib/amcheck/verify_heapam.c
    @@ -71,7 +71,7 @@ typedef struct ToastedAttribute
     	struct varatt_external toast_pointer;
     	BlockNumber blkno;			/* block in main table */
     	OffsetNumber offnum;		/* offset in main table */
    -	AttrNumber	attnum;			/* attribute in main table */
    +	AttrNumber	attphysnum;			/* attribute in main table */
     } ToastedAttribute;
     
     /*
    @@ -130,7 +130,7 @@ typedef struct HeapCheckContext
     
     	/* Values for iterating over attributes within the tuple */
     	uint32		offset;			/* offset in tuple data */
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     
     	/* True if tuple's xmax makes it eligible for pruning */
     	bool		tuple_could_be_pruned;
    @@ -272,10 +272,10 @@ verify_heapam(PG_FUNCTION_ARGS)
     
     	/*
     	 * If we report corruption when not examining some individual attribute,
    -	 * we need attnum to be reported as NULL.  Set that up before any
    +	 * we need attphysnum to be reported as NULL.  Set that up before any
     	 * corruption reporting might happen.
     	 */
    -	ctx.attnum = -1;
    +	ctx.attphysnum = -1;
     
     	/* Construct the tuplestore and tuple descriptor */
     	SetSingleFuncCall(fcinfo, 0);
    @@ -552,7 +552,7 @@ verify_heapam(PG_FUNCTION_ARGS)
     static void
     report_corruption_internal(Tuplestorestate *tupstore, TupleDesc tupdesc,
     						   BlockNumber blkno, OffsetNumber offnum,
    -						   AttrNumber attnum, char *msg)
    +						   AttrNumber attphysnum, char *msg)
     {
     	Datum		values[HEAPCHECK_RELATION_COLS];
     	bool		nulls[HEAPCHECK_RELATION_COLS];
    @@ -562,8 +562,8 @@ report_corruption_internal(Tuplestorestate *tupstore, TupleDesc tupdesc,
     	MemSet(nulls, 0, sizeof(nulls));
     	values[0] = Int64GetDatum(blkno);
     	values[1] = Int32GetDatum(offnum);
    -	values[2] = Int32GetDatum(attnum);
    -	nulls[2] = (attnum < 0);
    +	values[2] = Int32GetDatum(attphysnum);
    +	nulls[2] = (attphysnum < 0);
     	values[3] = CStringGetTextDatum(msg);
     
     	/*
    @@ -591,7 +591,7 @@ static void
     report_corruption(HeapCheckContext *ctx, char *msg)
     {
     	report_corruption_internal(ctx->tupstore, ctx->tupdesc, ctx->blkno,
    -							   ctx->offnum, ctx->attnum, msg);
    +							   ctx->offnum, ctx->attphysnum, msg);
     	ctx->is_corrupt = true;
     }
     
    @@ -608,7 +608,7 @@ report_toast_corruption(HeapCheckContext *ctx, ToastedAttribute *ta,
     						char *msg)
     {
     	report_corruption_internal(ctx->tupstore, ctx->tupdesc, ta->blkno,
    -							   ta->offnum, ta->attnum, msg);
    +							   ta->offnum, ta->attphysnum, msg);
     	ctx->is_corrupt = true;
     }
     
    @@ -1272,7 +1272,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
     	struct varatt_external toast_pointer;
     
     	infomask = ctx->tuphdr->t_infomask;
    -	thisatt = TupleDescAttr(RelationGetDescr(ctx->rel), ctx->attnum);
    +	thisatt = TupleDescAttr(RelationGetDescr(ctx->rel), ctx->attphysnum);
     
     	tp = (char *) ctx->tuphdr + ctx->tuphdr->t_hoff;
     
    @@ -1287,7 +1287,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
     	}
     
     	/* Skip null values */
    -	if (infomask & HEAP_HASNULL && att_isnull(ctx->attnum, ctx->tuphdr->t_bits))
    +	if (infomask & HEAP_HASNULL && att_isnull(ctx->attphysnum, ctx->tuphdr->t_bits))
     		return true;
     
     	/* Skip non-varlena values, but update offset first */
    @@ -1448,7 +1448,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
     		VARATT_EXTERNAL_GET_POINTER(ta->toast_pointer, attr);
     		ta->blkno = ctx->blkno;
     		ta->offnum = ctx->offnum;
    -		ta->attnum = ctx->attnum;
    +		ta->attphysnum = ctx->attphysnum;
     		ctx->toasted_attributes = lappend(ctx->toasted_attributes, ta);
     	}
     
    @@ -1560,12 +1560,12 @@ check_tuple(HeapCheckContext *ctx)
     	 * attributes collected from the page.
     	 */
     	ctx->offset = 0;
    -	for (ctx->attnum = 0; ctx->attnum < ctx->natts; ctx->attnum++)
    +	for (ctx->attphysnum = 0; ctx->attphysnum < ctx->natts; ctx->attphysnum++)
     		if (!check_tuple_attribute(ctx))
     			break;				/* cannot continue */
     
    -	/* revert attnum to -1 until we again examine individual attributes */
    -	ctx->attnum = -1;
    +	/* revert attphysnum to -1 until we again examine individual attributes */
    +	ctx->attphysnum = -1;
     }
     
     /*
    diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c
    index 2beeebb163..f1d935a538 100644
    --- a/contrib/amcheck/verify_nbtree.c
    +++ b/contrib/amcheck/verify_nbtree.c
    @@ -2575,7 +2575,7 @@ bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup)
     
     		/* Assume untoasted/already normalized datum initially */
     		toast_free[i] = false;
    -		normalized[i] = index_getattr(itup, att->attnum,
    +		normalized[i] = index_getattr(itup, att->attphysnum,
     									  tupleDescriptor,
     									  &isnull[i]);
     		if (att->attbyval || att->attlen != -1 || isnull[i])
    diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
    index a561d1d652..306d5ec054 100644
    --- a/contrib/dblink/dblink.c
    +++ b/contrib/dblink/dblink.c
    @@ -1694,7 +1694,7 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
     	src_pkattvals = get_text_array_contents(src_pkattvals_arry, &src_nitems);
     
     	/*
    -	 * There should be one source array key value for each key attnum
    +	 * There should be one source array key value for each key attphysnum
     	 */
     	if (src_nitems != pknumatts)
     		ereport(ERROR,
    @@ -1708,7 +1708,7 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
     	tgt_pkattvals = get_text_array_contents(tgt_pkattvals_arry, &tgt_nitems);
     
     	/*
    -	 * There should be one target array key value for each key attnum
    +	 * There should be one target array key value for each key attphysnum
     	 */
     	if (tgt_nitems != pknumatts)
     		ereport(ERROR,
    @@ -1780,7 +1780,7 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
     	tgt_pkattvals = get_text_array_contents(tgt_pkattvals_arry, &tgt_nitems);
     
     	/*
    -	 * There should be one target array key value for each key attnum
    +	 * There should be one target array key value for each key attphysnum
     	 */
     	if (tgt_nitems != pknumatts)
     		ereport(ERROR,
    @@ -1859,7 +1859,7 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
     	src_pkattvals = get_text_array_contents(src_pkattvals_arry, &src_nitems);
     
     	/*
    -	 * There should be one source array key value for each key attnum
    +	 * There should be one source array key value for each key attphysnum
     	 */
     	if (src_nitems != pknumatts)
     		ereport(ERROR,
    @@ -1873,7 +1873,7 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
     	tgt_pkattvals = get_text_array_contents(tgt_pkattvals_arry, &tgt_nitems);
     
     	/*
    -	 * There should be one target array key value for each key attnum
    +	 * There should be one target array key value for each key attphysnum
     	 */
     	if (tgt_nitems != pknumatts)
     		ereport(ERROR,
    @@ -2902,7 +2902,7 @@ escape_param_str(const char *str)
      *
      * The user supplies an int2vector of 1-based logical attnums, plus a count
      * argument (the need for the separate count argument is historical, but we
    - * still check it).  We check that each attnum corresponds to a valid,
    + * still check it).  We check that each attphysnum corresponds to a valid,
      * non-dropped attribute of the rel.  We do *not* prevent attnums from being
      * listed twice, though the actual use-case for such things is dubious.
      * Note that before Postgres 9.0, the user's attnums were interpreted as
    @@ -2923,7 +2923,7 @@ validate_pkattnums(Relation rel,
     	/* Don't take more array elements than there are */
     	pknumatts_arg = Min(pknumatts_arg, pkattnums_arg->dim1);
     
    -	/* Must have at least one pk attnum selected */
    +	/* Must have at least one pk attphysnum selected */
     	if (pknumatts_arg <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c
    index 4773cadec0..7980f67a14 100644
    --- a/contrib/file_fdw/file_fdw.c
    +++ b/contrib/file_fdw/file_fdw.c
    @@ -430,7 +430,7 @@ get_file_fdw_attribute_options(Oid relid)
     	Relation	rel;
     	TupleDesc	tupleDesc;
     	AttrNumber	natts;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	List	   *fnncolumns = NIL;
     	List	   *fncolumns = NIL;
     
    @@ -441,9 +441,9 @@ get_file_fdw_attribute_options(Oid relid)
     	natts = tupleDesc->natts;
     
     	/* Retrieve FDW options for all user-defined attributes. */
    -	for (attnum = 1; attnum <= natts; attnum++)
    +	for (attphysnum = 1; attphysnum <= natts; attphysnum++)
     	{
    -		Form_pg_attribute attr = TupleDescAttr(tupleDesc, attnum - 1);
    +		Form_pg_attribute attr = TupleDescAttr(tupleDesc, attphysnum - 1);
     		List	   *options;
     		ListCell   *lc;
     
    @@ -451,7 +451,7 @@ get_file_fdw_attribute_options(Oid relid)
     		if (attr->attisdropped)
     			continue;
     
    -		options = GetForeignColumnOptions(relid, attnum);
    +		options = GetForeignColumnOptions(relid, attphysnum);
     		foreach(lc, options)
     		{
     			DefElem    *def = (DefElem *) lfirst(lc);
    @@ -852,7 +852,7 @@ check_selective_binary_conversion(RelOptInfo *baserel,
     	ListCell   *lc;
     	Relation	rel;
     	TupleDesc	tupleDesc;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	Bitmapset  *attrs_used = NULL;
     	bool		has_wholerow = false;
     	int			numattrs;
    @@ -895,25 +895,25 @@ check_selective_binary_conversion(RelOptInfo *baserel,
     	rel = table_open(foreigntableid, AccessShareLock);
     	tupleDesc = RelationGetDescr(rel);
     
    -	while ((attnum = bms_first_member(attrs_used)) >= 0)
    +	while ((attphysnum = bms_first_member(attrs_used)) >= 0)
     	{
     		/* Adjust for system attributes. */
    -		attnum += FirstLowInvalidHeapAttributeNumber;
    +		attphysnum += FirstLowInvalidHeapAttributeNumber;
     
    -		if (attnum == 0)
    +		if (attphysnum == 0)
     		{
     			has_wholerow = true;
     			break;
     		}
     
     		/* Ignore system attributes. */
    -		if (attnum < 0)
    +		if (attphysnum < 0)
     			continue;
     
     		/* Get user attributes. */
    -		if (attnum > 0)
    +		if (attphysnum > 0)
     		{
    -			Form_pg_attribute attr = TupleDescAttr(tupleDesc, attnum - 1);
    +			Form_pg_attribute attr = TupleDescAttr(tupleDesc, attphysnum - 1);
     			char	   *attname = NameStr(attr->attname);
     
     			/* Skip dropped attributes (probably shouldn't see any here). */
    diff --git a/contrib/lo/lo.c b/contrib/lo/lo.c
    index 457be26c4e..367e2fb866 100644
    --- a/contrib/lo/lo.c
    +++ b/contrib/lo/lo.c
    @@ -24,7 +24,7 @@ Datum
     lo_manage(PG_FUNCTION_ARGS)
     {
     	TriggerData *trigdata = (TriggerData *) fcinfo->context;
    -	int			attnum;			/* attribute number to monitor	*/
    +	int			attphysnum;			/* attribute number to monitor	*/
     	char	  **args;			/* Args containing attr name	*/
     	TupleDesc	tupdesc;		/* Tuple Descriptor				*/
     	HeapTuple	rettuple;		/* Tuple to be returned			*/
    @@ -61,9 +61,9 @@ lo_manage(PG_FUNCTION_ARGS)
     	isdelete = TRIGGER_FIRED_BY_DELETE(trigdata->tg_event);
     
     	/* Get the column we're interested in */
    -	attnum = SPI_fnumber(tupdesc, args[0]);
    +	attphysnum = SPI_fnumber(tupdesc, args[0]);
     
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		elog(ERROR, "%s: column \"%s\" does not exist",
     			 trigdata->tg_trigger->tgname, args[0]);
     
    @@ -74,10 +74,10 @@ lo_manage(PG_FUNCTION_ARGS)
     	 * object associated with the original value is unlinked.
     	 */
     	if (newtuple != NULL &&
    -		bms_is_member(attnum - FirstLowInvalidHeapAttributeNumber, trigdata->tg_updatedcols))
    +		bms_is_member(attphysnum - FirstLowInvalidHeapAttributeNumber, trigdata->tg_updatedcols))
     	{
    -		char	   *orig = SPI_getvalue(trigtuple, tupdesc, attnum);
    -		char	   *newv = SPI_getvalue(newtuple, tupdesc, attnum);
    +		char	   *orig = SPI_getvalue(trigtuple, tupdesc, attphysnum);
    +		char	   *newv = SPI_getvalue(newtuple, tupdesc, attphysnum);
     
     		if (orig != NULL && (newv == NULL || strcmp(orig, newv) != 0))
     			DirectFunctionCall1(be_lo_unlink,
    @@ -96,7 +96,7 @@ lo_manage(PG_FUNCTION_ARGS)
     	 */
     	if (isdelete)
     	{
    -		char	   *orig = SPI_getvalue(trigtuple, tupdesc, attnum);
    +		char	   *orig = SPI_getvalue(trigtuple, tupdesc, attphysnum);
     
     		if (orig != NULL)
     		{
    diff --git a/contrib/pageinspect/expected/brin.out b/contrib/pageinspect/expected/brin.out
    index d19cdc3b95..832117b565 100644
    --- a/contrib/pageinspect/expected/brin.out
    +++ b/contrib/pageinspect/expected/brin.out
    @@ -42,10 +42,10 @@ SELECT * FROM brin_revmap_data(get_raw_page('test1_a_idx', 1)) LIMIT 5;
     (5 rows)
     
     SELECT * FROM brin_page_items(get_raw_page('test1_a_idx', 2), 'test1_a_idx')
    -    ORDER BY blknum, attnum LIMIT 5;
    - itemoffset | blknum | attnum | allnulls | hasnulls | placeholder |  value   
    -------------+--------+--------+----------+----------+-------------+----------
    -          1 |      0 |      1 | f        | f        | f           | {1 .. 1}
    +    ORDER BY blknum, attphysnum LIMIT 5;
    + itemoffset | blknum | attphysnum | allnulls | hasnulls | placeholder |  value   
    +------------+--------+------------+----------+----------+-------------+----------
    +          1 |      0 |          1 | f        | f        | f           | {1 .. 1}
     (1 row)
     
     -- Failure for non-BRIN index.
    diff --git a/contrib/pageinspect/pageinspect--1.2--1.3.sql b/contrib/pageinspect/pageinspect--1.2--1.3.sql
    index 9c55a6e598..9d3af061b6 100644
    --- a/contrib/pageinspect/pageinspect--1.2--1.3.sql
    +++ b/contrib/pageinspect/pageinspect--1.2--1.3.sql
    @@ -34,7 +34,7 @@ LANGUAGE C STRICT;
     CREATE FUNCTION brin_page_items(IN page bytea, IN index_oid regclass,
     	OUT itemoffset int,
     	OUT blknum int,
    -	OUT attnum int,
    +	OUT attphysnum int,
     	OUT allnulls bool,
     	OUT hasnulls bool,
     	OUT placeholder bool,
    diff --git a/contrib/pageinspect/pageinspect--1.5.sql b/contrib/pageinspect/pageinspect--1.5.sql
    index 1e40c3c97e..1e759b504d 100644
    --- a/contrib/pageinspect/pageinspect--1.5.sql
    +++ b/contrib/pageinspect/pageinspect--1.5.sql
    @@ -219,7 +219,7 @@ LANGUAGE C STRICT PARALLEL SAFE;
     CREATE FUNCTION brin_page_items(IN page bytea, IN index_oid regclass,
     	OUT itemoffset int,
     	OUT blknum int,
    -	OUT attnum int,
    +	OUT attphysnum int,
     	OUT allnulls bool,
     	OUT hasnulls bool,
     	OUT placeholder bool,
    diff --git a/contrib/pageinspect/pageinspect--1.8--1.9.sql b/contrib/pageinspect/pageinspect--1.8--1.9.sql
    index be89a64ca1..389d981f82 100644
    --- a/contrib/pageinspect/pageinspect--1.8--1.9.sql
    +++ b/contrib/pageinspect/pageinspect--1.8--1.9.sql
    @@ -127,7 +127,7 @@ DROP FUNCTION brin_page_items(IN page bytea, IN index_oid regclass);
     CREATE FUNCTION brin_page_items(IN page bytea, IN index_oid regclass,
         OUT itemoffset int,
         OUT blknum int8,
    -    OUT attnum int,
    +    OUT attphysnum int,
         OUT allnulls bool,
         OUT hasnulls bool,
         OUT placeholder bool,
    diff --git a/contrib/pageinspect/sql/brin.sql b/contrib/pageinspect/sql/brin.sql
    index 45098c1ef5..555e83f98a 100644
    --- a/contrib/pageinspect/sql/brin.sql
    +++ b/contrib/pageinspect/sql/brin.sql
    @@ -13,7 +13,7 @@ SELECT * FROM brin_revmap_data(get_raw_page('test1_a_idx', 0)) LIMIT 5;
     SELECT * FROM brin_revmap_data(get_raw_page('test1_a_idx', 1)) LIMIT 5;
     
     SELECT * FROM brin_page_items(get_raw_page('test1_a_idx', 2), 'test1_a_idx')
    -    ORDER BY blknum, attnum LIMIT 5;
    +    ORDER BY blknum, attphysnum LIMIT 5;
     
     -- Failure for non-BRIN index.
     CREATE INDEX test1_a_btree ON test1 (a);
    diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c
    index 8f4d8a5022..5cd519511e 100644
    --- a/contrib/postgres_fdw/deparse.c
    +++ b/contrib/postgres_fdw/deparse.c
    @@ -1890,13 +1890,13 @@ deparseInsertSql(StringInfo buf, RangeTblEntry *rte,
     		first = true;
     		foreach(lc, targetAttrs)
     		{
    -			int			attnum = lfirst_int(lc);
    +			int			attphysnum = lfirst_int(lc);
     
     			if (!first)
     				appendStringInfoString(buf, ", ");
     			first = false;
     
    -			deparseColumnRef(buf, rtindex, attnum, rte, false);
    +			deparseColumnRef(buf, rtindex, attphysnum, rte, false);
     		}
     
     		appendStringInfoString(buf, ") VALUES (");
    @@ -1905,8 +1905,8 @@ deparseInsertSql(StringInfo buf, RangeTblEntry *rte,
     		first = true;
     		foreach(lc, targetAttrs)
     		{
    -			int			attnum = lfirst_int(lc);
    -			Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
    +			int			attphysnum = lfirst_int(lc);
    +			Form_pg_attribute attr = TupleDescAttr(tupdesc, attphysnum - 1);
     
     			if (!first)
     				appendStringInfoString(buf, ", ");
    @@ -1971,8 +1971,8 @@ rebuildInsertSql(StringInfo buf, Relation rel,
     		first = true;
     		foreach(lc, target_attrs)
     		{
    -			int			attnum = lfirst_int(lc);
    -			Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
    +			int			attphysnum = lfirst_int(lc);
    +			Form_pg_attribute attr = TupleDescAttr(tupdesc, attphysnum - 1);
     
     			if (!first)
     				appendStringInfoString(buf, ", ");
    @@ -2021,14 +2021,14 @@ deparseUpdateSql(StringInfo buf, RangeTblEntry *rte,
     	first = true;
     	foreach(lc, targetAttrs)
     	{
    -		int			attnum = lfirst_int(lc);
    -		Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
    +		int			attphysnum = lfirst_int(lc);
    +		Form_pg_attribute attr = TupleDescAttr(tupdesc, attphysnum - 1);
     
     		if (!first)
     			appendStringInfoString(buf, ", ");
     		first = false;
     
    -		deparseColumnRef(buf, rtindex, attnum, rte, false);
    +		deparseColumnRef(buf, rtindex, attphysnum, rte, false);
     		if (attr->attgenerated)
     			appendStringInfoString(buf, " = DEFAULT");
     		else
    @@ -2099,7 +2099,7 @@ deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root,
     	forboth(lc, targetlist, lc2, targetAttrs)
     	{
     		TargetEntry *tle = lfirst_node(TargetEntry, lc);
    -		int			attnum = lfirst_int(lc2);
    +		int			attphysnum = lfirst_int(lc2);
     
     		/* update's new-value expressions shouldn't be resjunk */
     		Assert(!tle->resjunk);
    @@ -2108,7 +2108,7 @@ deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root,
     			appendStringInfoString(buf, ", ");
     		first = false;
     
    -		deparseColumnRef(buf, rtindex, attnum, rte, false);
    +		deparseColumnRef(buf, rtindex, attphysnum, rte, false);
     		appendStringInfoString(buf, " = ");
     		deparseExpr((Expr *) tle->expr, &context);
     	}
    diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
    index d56951153b..10effe7387 100644
    --- a/contrib/postgres_fdw/postgres_fdw.c
    +++ b/contrib/postgres_fdw/postgres_fdw.c
    @@ -197,7 +197,7 @@ typedef struct PgFdwModifyState
     	List	   *retrieved_attrs;	/* attr numbers retrieved by RETURNING */
     
     	/* info about parameters for prepared statement */
    -	AttrNumber	ctidAttno;		/* attnum of input resjunk ctid column */
    +	AttrNumber	ctidAttno;		/* attphysnum of input resjunk ctid column */
     	int			p_nums;			/* number of parameters to transmit */
     	FmgrInfo   *p_flinfo;		/* output conversion functions for them */
     
    @@ -240,8 +240,8 @@ typedef struct PgFdwDirectModifyState
     	int			next_tuple;		/* index of next one to return */
     	Relation	resultRel;		/* relcache entry for the target relation */
     	AttrNumber *attnoMap;		/* array of attnums of input user columns */
    -	AttrNumber	ctidAttno;		/* attnum of input ctid column */
    -	AttrNumber	oidAttno;		/* attnum of input oid column */
    +	AttrNumber	ctidAttno;		/* attphysnum of input ctid column */
    +	AttrNumber	oidAttno;		/* attphysnum of input oid column */
     	bool		hasSystemCols;	/* are there system columns of resultRel? */
     
     	/* working memory context */
    @@ -1800,14 +1800,14 @@ postgresPlanForeignModify(PlannerInfo *root,
     		 rel->trigdesc->trig_update_before_row))
     	{
     		TupleDesc	tupdesc = RelationGetDescr(rel);
    -		int			attnum;
    +		int			attphysnum;
     
    -		for (attnum = 1; attnum <= tupdesc->natts; attnum++)
    +		for (attphysnum = 1; attphysnum <= tupdesc->natts; attphysnum++)
     		{
    -			Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
    +			Form_pg_attribute attr = TupleDescAttr(tupdesc, attphysnum - 1);
     
     			if (!attr->attisdropped)
    -				targetAttrs = lappend_int(targetAttrs, attnum);
    +				targetAttrs = lappend_int(targetAttrs, attphysnum);
     		}
     	}
     	else if (operation == CMD_UPDATE)
    @@ -2139,7 +2139,7 @@ postgresBeginForeignInsert(ModifyTableState *mtstate,
     	Relation	rel = resultRelInfo->ri_RelationDesc;
     	RangeTblEntry *rte;
     	TupleDesc	tupdesc = RelationGetDescr(rel);
    -	int			attnum;
    +	int			attphysnum;
     	int			values_end_len;
     	StringInfoData sql;
     	List	   *targetAttrs = NIL;
    @@ -2164,12 +2164,12 @@ postgresBeginForeignInsert(ModifyTableState *mtstate,
     	initStringInfo(&sql);
     
     	/* We transmit all columns that are defined in the foreign table. */
    -	for (attnum = 1; attnum <= tupdesc->natts; attnum++)
    +	for (attphysnum = 1; attphysnum <= tupdesc->natts; attphysnum++)
     	{
    -		Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
    +		Form_pg_attribute attr = TupleDescAttr(tupdesc, attphysnum - 1);
     
     		if (!attr->attisdropped)
    -			targetAttrs = lappend_int(targetAttrs, attnum);
    +			targetAttrs = lappend_int(targetAttrs, attphysnum);
     	}
     
     	/* Check if we add the ON CONFLICT clause to the remote query. */
    @@ -4026,8 +4026,8 @@ create_foreign_modify(EState *estate,
     		/* Set up for remaining transmittable parameters */
     		foreach(lc, fmstate->target_attrs)
     		{
    -			int			attnum = lfirst_int(lc);
    -			Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
    +			int			attphysnum = lfirst_int(lc);
    +			Form_pg_attribute attr = TupleDescAttr(tupdesc, attphysnum - 1);
     
     			Assert(!attr->attisdropped);
     
    @@ -4279,15 +4279,15 @@ convert_prep_stmt_params(PgFdwModifyState *fmstate,
     			j = (tupleid != NULL) ? 1 : 0;
     			foreach(lc, fmstate->target_attrs)
     			{
    -				int			attnum = lfirst_int(lc);
    -				Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
    +				int			attphysnum = lfirst_int(lc);
    +				Form_pg_attribute attr = TupleDescAttr(tupdesc, attphysnum - 1);
     				Datum		value;
     				bool		isnull;
     
     				/* Ignore generated columns; they are set to DEFAULT */
     				if (attr->attgenerated)
     					continue;
    -				value = slot_getattr(slots[i], attnum, &isnull);
    +				value = slot_getattr(slots[i], attphysnum, &isnull);
     				if (isnull)
     					p_values[pindex] = NULL;
     				else
    @@ -5330,10 +5330,10 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid)
     							   "  JOIN pg_namespace n ON "
     							   "    relnamespace = n.oid "
     							   "  LEFT JOIN pg_attribute a ON "
    -							   "    attrelid = c.oid AND attnum > 0 "
    +							   "    attrelid = c.oid AND attphysnum > 0 "
     							   "      AND NOT attisdropped "
     							   "  LEFT JOIN pg_attrdef ad ON "
    -							   "    adrelid = c.oid AND adnum = attnum ");
    +							   "    adrelid = c.oid AND adnum = attphysnum ");
     
     		if (import_collate)
     			appendStringInfoString(&buf,
    @@ -5383,7 +5383,7 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid)
     		}
     
     		/* Append ORDER BY at the end of query to ensure output ordering */
    -		appendStringInfoString(&buf, " ORDER BY c.relname, a.attnum");
    +		appendStringInfoString(&buf, " ORDER BY c.relname, a.attphysnum");
     
     		/* Fetch the data */
     		res = pgfdw_exec_query(conn, buf.data, NULL);
    diff --git a/contrib/sepgsql/dml.c b/contrib/sepgsql/dml.c
    index 3bb98dfb06..4f43665f70 100644
    --- a/contrib/sepgsql/dml.c
    +++ b/contrib/sepgsql/dml.c
    @@ -61,7 +61,7 @@ fixup_whole_row_references(Oid relOid, Bitmapset *columns)
     
     	for (attno = 1; attno <= natts; attno++)
     	{
    -		tuple = SearchSysCache2(ATTNUM,
    +		tuple = SearchSysCache2(ATTPHYSNUM,
     								ObjectIdGetDatum(relOid),
     								Int16GetDatum(attno));
     		if (!HeapTupleIsValid(tuple))
    @@ -117,7 +117,7 @@ fixup_inherited_columns(Oid parentId, Oid childId, Bitmapset *columns)
     		}
     
     		attname = get_attname(parentId, attno, false);
    -		attno = get_attnum(childId, attname);
    +		attno = get_attphysnum(childId, attname);
     		if (attno == InvalidAttrNumber)
     			elog(ERROR, "cache lookup failed for attribute %s of relation %u",
     				 attname, childId);
    @@ -232,7 +232,7 @@ check_relation_privileges(Oid relOid,
     
     	while ((index = bms_first_member(columns)) >= 0)
     	{
    -		AttrNumber	attnum;
    +		AttrNumber	attphysnum;
     		uint32		column_perms = 0;
     
     		if (bms_is_member(index, selected))
    @@ -251,11 +251,11 @@ check_relation_privileges(Oid relOid,
     			continue;
     
     		/* obtain column's permission */
    -		attnum = index + FirstLowInvalidHeapAttributeNumber;
    +		attphysnum = index + FirstLowInvalidHeapAttributeNumber;
     
     		object.classId = RelationRelationId;
     		object.objectId = relOid;
    -		object.objectSubId = attnum;
    +		object.objectSubId = attphysnum;
     		audit_name = getObjectDescription(&object, false);
     
     		result = sepgsql_avc_check_perms(&object,
    diff --git a/contrib/sepgsql/label.c b/contrib/sepgsql/label.c
    index e4c98b7eae..97dccf385f 100644
    --- a/contrib/sepgsql/label.c
    +++ b/contrib/sepgsql/label.c
    @@ -805,7 +805,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
     
     				object.classId = RelationRelationId;
     				object.objectId = attForm->attrelid;
    -				object.objectSubId = attForm->attnum;
    +				object.objectSubId = attForm->attphysnum;
     				break;
     
     			case ProcedureRelationId:
    diff --git a/contrib/sepgsql/relation.c b/contrib/sepgsql/relation.c
    index 8767988c4d..b1ad4a6636 100644
    --- a/contrib/sepgsql/relation.c
    +++ b/contrib/sepgsql/relation.c
    @@ -40,7 +40,7 @@ static void sepgsql_index_modify(Oid indexOid);
      * although it also defines columns in addition to table.
      */
     void
    -sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum)
    +sepgsql_attribute_post_create(Oid relOid, AttrNumber attphysnum)
     {
     	Relation	rel;
     	ScanKeyData skey[2];
    @@ -72,17 +72,17 @@ sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum)
     				BTEqualStrategyNumber, F_OIDEQ,
     				ObjectIdGetDatum(relOid));
     	ScanKeyInit(&skey[1],
    -				Anum_pg_attribute_attnum,
    +				Anum_pg_attribute_attphysnum,
     				BTEqualStrategyNumber, F_INT2EQ,
    -				Int16GetDatum(attnum));
    +				Int16GetDatum(attphysnum));
     
    -	sscan = systable_beginscan(rel, AttributeRelidNumIndexId, true,
    +	sscan = systable_beginscan(rel, AttributeRelidPhysNumIndexId, true,
     							   SnapshotSelf, 2, &skey[0]);
     
     	tuple = systable_getnext(sscan);
     	if (!HeapTupleIsValid(tuple))
     		elog(ERROR, "could not find tuple for column %d of relation %u",
    -			 attnum, relOid);
    +			 attphysnum, relOid);
     
     	attForm = (Form_pg_attribute) GETSTRUCT(tuple);
     
    @@ -114,7 +114,7 @@ sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum)
     	 */
     	object.classId = RelationRelationId;
     	object.objectId = relOid;
    -	object.objectSubId = attnum;
    +	object.objectSubId = attphysnum;
     	SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
     
     	systable_endscan(sscan);
    @@ -130,7 +130,7 @@ sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum)
      * It checks privileges to drop the supplied column.
      */
     void
    -sepgsql_attribute_drop(Oid relOid, AttrNumber attnum)
    +sepgsql_attribute_drop(Oid relOid, AttrNumber attphysnum)
     {
     	ObjectAddress object;
     	char	   *audit_name;
    @@ -144,7 +144,7 @@ sepgsql_attribute_drop(Oid relOid, AttrNumber attnum)
     	 */
     	object.classId = RelationRelationId;
     	object.objectId = relOid;
    -	object.objectSubId = attnum;
    +	object.objectSubId = attphysnum;
     	audit_name = getObjectIdentity(&object, false);
     
     	sepgsql_avc_check_perms(&object,
    @@ -162,7 +162,7 @@ sepgsql_attribute_drop(Oid relOid, AttrNumber attnum)
      * by the `seclabel'.
      */
     void
    -sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
    +sepgsql_attribute_relabel(Oid relOid, AttrNumber attphysnum,
     						  const char *seclabel)
     {
     	ObjectAddress object;
    @@ -176,7 +176,7 @@ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
     
     	object.classId = RelationRelationId;
     	object.objectId = relOid;
    -	object.objectSubId = attnum;
    +	object.objectSubId = attphysnum;
     	audit_name = getObjectIdentity(&object, false);
     
     	/*
    @@ -206,7 +206,7 @@ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
      * It checks privileges to alter the supplied column.
      */
     void
    -sepgsql_attribute_setattr(Oid relOid, AttrNumber attnum)
    +sepgsql_attribute_setattr(Oid relOid, AttrNumber attphysnum)
     {
     	ObjectAddress object;
     	char	   *audit_name;
    @@ -220,7 +220,7 @@ sepgsql_attribute_setattr(Oid relOid, AttrNumber attnum)
     	 */
     	object.classId = RelationRelationId;
     	object.objectId = relOid;
    -	object.objectSubId = attnum;
    +	object.objectSubId = attphysnum;
     	audit_name = getObjectIdentity(&object, false);
     
     	sepgsql_avc_check_perms(&object,
    @@ -363,7 +363,7 @@ sepgsql_relation_post_create(Oid relOid)
     					BTEqualStrategyNumber, F_OIDEQ,
     					ObjectIdGetDatum(relOid));
     
    -		ascan = systable_beginscan(arel, AttributeRelidNumIndexId, true,
    +		ascan = systable_beginscan(arel, AttributeRelidPhysNumIndexId, true,
     								   SnapshotSelf, 1, &akey);
     
     		while (HeapTupleIsValid(atup = systable_getnext(ascan)))
    @@ -392,7 +392,7 @@ sepgsql_relation_post_create(Oid relOid)
     
     			object.classId = RelationRelationId;
     			object.objectId = relOid;
    -			object.objectSubId = attForm->attnum;
    +			object.objectSubId = attForm->attphysnum;
     			SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ccontext);
     
     			pfree(ccontext);
    @@ -490,7 +490,7 @@ sepgsql_relation_drop(Oid relOid)
     		HeapTuple	atttup;
     		int			i;
     
    -		attrList = SearchSysCacheList1(ATTNUM, ObjectIdGetDatum(relOid));
    +		attrList = SearchSysCacheList1(ATTPHYSNUM, ObjectIdGetDatum(relOid));
     		for (i = 0; i < attrList->n_members; i++)
     		{
     			atttup = &attrList->members[i]->tuple;
    @@ -501,7 +501,7 @@ sepgsql_relation_drop(Oid relOid)
     
     			object.classId = RelationRelationId;
     			object.objectId = relOid;
    -			object.objectSubId = attForm->attnum;
    +			object.objectSubId = attForm->attphysnum;
     			audit_name = getObjectIdentity(&object, false);
     
     			sepgsql_avc_check_perms(&object,
    diff --git a/contrib/sepgsql/sepgsql.h b/contrib/sepgsql/sepgsql.h
    index 70f6203496..86e1562630 100644
    --- a/contrib/sepgsql/sepgsql.h
    +++ b/contrib/sepgsql/sepgsql.h
    @@ -307,11 +307,11 @@ extern void sepgsql_schema_rename(Oid namespaceId);
     /*
      * relation.c
      */
    -extern void sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum);
    -extern void sepgsql_attribute_drop(Oid relOid, AttrNumber attnum);
    -extern void sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
    +extern void sepgsql_attribute_post_create(Oid relOid, AttrNumber attphysnum);
    +extern void sepgsql_attribute_drop(Oid relOid, AttrNumber attphysnum);
    +extern void sepgsql_attribute_relabel(Oid relOid, AttrNumber attphysnum,
     									  const char *seclabel);
    -extern void sepgsql_attribute_setattr(Oid relOid, AttrNumber attnum);
    +extern void sepgsql_attribute_setattr(Oid relOid, AttrNumber attphysnum);
     extern void sepgsql_relation_post_create(Oid relOid);
     extern void sepgsql_relation_drop(Oid relOid);
     extern void sepgsql_relation_truncate(Oid relOid);
    diff --git a/contrib/spi/autoinc.c b/contrib/spi/autoinc.c
    index 8bf742230e..1b82c2ae29 100644
    --- a/contrib/spi/autoinc.c
    +++ b/contrib/spi/autoinc.c
    @@ -70,23 +70,23 @@ autoinc(PG_FUNCTION_ARGS)
     
     	for (i = 0; i < nargs;)
     	{
    -		int			attnum = SPI_fnumber(tupdesc, args[i]);
    +		int			attphysnum = SPI_fnumber(tupdesc, args[i]);
     		int32		val;
     		Datum		seqname;
     
    -		if (attnum <= 0)
    +		if (attphysnum <= 0)
     			ereport(ERROR,
     					(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
     					 errmsg("\"%s\" has no attribute \"%s\"",
     							relname, args[i])));
     
    -		if (SPI_gettypeid(tupdesc, attnum) != INT4OID)
    +		if (SPI_gettypeid(tupdesc, attphysnum) != INT4OID)
     			ereport(ERROR,
     					(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
     					 errmsg("attribute \"%s\" of \"%s\" must be type INT4",
     							args[i], relname)));
     
    -		val = DatumGetInt32(SPI_getbinval(rettuple, tupdesc, attnum, &isnull));
    +		val = DatumGetInt32(SPI_getbinval(rettuple, tupdesc, attphysnum, &isnull));
     
     		if (!isnull && val != 0)
     		{
    @@ -95,7 +95,7 @@ autoinc(PG_FUNCTION_ARGS)
     		}
     
     		i++;
    -		chattrs[chnattrs] = attnum;
    +		chattrs[chnattrs] = attphysnum;
     		seqname = CStringGetTextDatum(args[i]);
     		newvals[chnattrs] = DirectFunctionCall1(nextval, seqname);
     		/* nextval now returns int64; coerce down to int32 */
    diff --git a/contrib/spi/insert_username.c b/contrib/spi/insert_username.c
    index a2e1747ff7..fbf3514942 100644
    --- a/contrib/spi/insert_username.c
    +++ b/contrib/spi/insert_username.c
    @@ -31,7 +31,7 @@ insert_username(PG_FUNCTION_ARGS)
     	Relation	rel;			/* triggered relation */
     	HeapTuple	rettuple = NULL;
     	TupleDesc	tupdesc;		/* tuple description */
    -	int			attnum;
    +	int			attphysnum;
     
     	/* sanity checks from autoinc.c */
     	if (!CALLED_AS_TRIGGER(fcinfo))
    @@ -65,14 +65,14 @@ insert_username(PG_FUNCTION_ARGS)
     	args = trigger->tgargs;
     	tupdesc = rel->rd_att;
     
    -	attnum = SPI_fnumber(tupdesc, args[0]);
    +	attphysnum = SPI_fnumber(tupdesc, args[0]);
     
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
     				 errmsg("\"%s\" has no attribute \"%s\"", relname, args[0])));
     
    -	if (SPI_gettypeid(tupdesc, attnum) != TEXTOID)
    +	if (SPI_gettypeid(tupdesc, attphysnum) != TEXTOID)
     		ereport(ERROR,
     				(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
     				 errmsg("attribute \"%s\" of \"%s\" must be type TEXT",
    @@ -84,7 +84,7 @@ insert_username(PG_FUNCTION_ARGS)
     
     	/* construct new tuple */
     	rettuple = heap_modify_tuple_by_cols(rettuple, tupdesc,
    -										 1, &attnum, &newval, &newnull);
    +										 1, &attphysnum, &newval, &newnull);
     
     	pfree(relname);
     
    diff --git a/contrib/spi/moddatetime.c b/contrib/spi/moddatetime.c
    index 3eb7004de9..6291ca4816 100644
    --- a/contrib/spi/moddatetime.c
    +++ b/contrib/spi/moddatetime.c
    @@ -32,7 +32,7 @@ moddatetime(PG_FUNCTION_ARGS)
     	TriggerData *trigdata = (TriggerData *) fcinfo->context;
     	Trigger    *trigger;		/* to get trigger name */
     	int			nargs;			/* # of arguments */
    -	int			attnum;			/* positional number of field to change */
    +	int			attphysnum;			/* positional number of field to change */
     	Oid			atttypid;		/* type OID of field to change */
     	Datum		newdt;			/* The current datetime. */
     	bool		newdtnull;		/* null flag for it */
    @@ -82,13 +82,13 @@ moddatetime(PG_FUNCTION_ARGS)
     	 * This gets the position in the tuple of the field we want. args[0] being
     	 * the name of the field to update, as passed in from the trigger.
     	 */
    -	attnum = SPI_fnumber(tupdesc, args[0]);
    +	attphysnum = SPI_fnumber(tupdesc, args[0]);
     
     	/*
     	 * This is where we check to see if the field we are supposed to update
     	 * even exists.
     	 */
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
     				 errmsg("\"%s\" has no attribute \"%s\"",
    @@ -98,7 +98,7 @@ moddatetime(PG_FUNCTION_ARGS)
     	 * Check the target field has an allowed type, and get the current
     	 * datetime as a value of that type.
     	 */
    -	atttypid = SPI_gettypeid(tupdesc, attnum);
    +	atttypid = SPI_gettypeid(tupdesc, attphysnum);
     	if (atttypid == TIMESTAMPOID)
     		newdt = DirectFunctionCall3(timestamp_in,
     									CStringGetDatum("now"),
    @@ -121,7 +121,7 @@ moddatetime(PG_FUNCTION_ARGS)
     
     	/* Replace the attnum'th column with newdt */
     	rettuple = heap_modify_tuple_by_cols(rettuple, tupdesc,
    -										 1, &attnum, &newdt, &newdtnull);
    +										 1, &attphysnum, &newdt, &newdtnull);
     
     	/* Clean up */
     	pfree(relname);
    diff --git a/contrib/test_decoding/test_decoding.c b/contrib/test_decoding/test_decoding.c
    index 3736da6784..3954427214 100644
    --- a/contrib/test_decoding/test_decoding.c
    +++ b/contrib/test_decoding/test_decoding.c
    @@ -554,7 +554,7 @@ tuple_to_stringinfo(StringInfo s, TupleDesc tupdesc, HeapTuple tuple, bool skip_
     		 * Don't print system columns, oid will already have been printed if
     		 * present.
     		 */
    -		if (attr->attnum < 0)
    +		if (attr->attphysnum < 0)
     			continue;
     
     		typid = attr->atttypid;
    diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c
    index b7c8f2c805..6a86c8cec8 100644
    --- a/contrib/vacuumlo/vacuumlo.c
    +++ b/contrib/vacuumlo/vacuumlo.c
    @@ -193,7 +193,7 @@ vacuumlo(const char *database, const struct _param *param)
     	buf[0] = '\0';
     	strcat(buf, "SELECT s.nspname, c.relname, a.attname ");
     	strcat(buf, "FROM pg_class c, pg_attribute a, pg_namespace s, pg_type t ");
    -	strcat(buf, "WHERE a.attnum > 0 AND NOT a.attisdropped ");
    +	strcat(buf, "WHERE a.attphysnum > 0 AND NOT a.attisdropped ");
     	strcat(buf, "      AND a.attrelid = c.oid ");
     	strcat(buf, "      AND a.atttypid = t.oid ");
     	strcat(buf, "      AND c.relnamespace = s.oid ");
    diff --git a/doc/src/sgml/amcheck.sgml b/doc/src/sgml/amcheck.sgml
    index 5d61a33936..bd6e7ef77f 100644
    --- a/doc/src/sgml/amcheck.sgml
    +++ b/doc/src/sgml/amcheck.sgml
    @@ -91,7 +91,7 @@ ORDER BY c.relpages DESC LIMIT 10;
                     | pg_description_o_c_o_index      |       21
                     | pg_attribute_relid_attnam_index |       14
                     | pg_proc_oid_index               |       10
    -                | pg_attribute_relid_attnum_index |        9
    +                | pg_attribute_relid_attphysnum_index |        9
                     | pg_amproc_fam_proc_index        |        5
                     | pg_amop_opr_fam_index           |        5
                     | pg_amop_fam_strat_index         |        5
    @@ -213,7 +213,7 @@ SET client_min_messages = DEBUG1;
                         endblock bigint,
                         blkno OUT bigint,
                         offnum OUT integer,
    -                    attnum OUT integer,
    +                    attphysnum OUT integer,
                         msg OUT text)
           returns setof record
          </function>
    diff --git a/doc/src/sgml/fdwhandler.sgml b/doc/src/sgml/fdwhandler.sgml
    index d0b5951019..e0f95fcfd4 100644
    --- a/doc/src/sgml/fdwhandler.sgml
    +++ b/doc/src/sgml/fdwhandler.sgml
    @@ -1759,7 +1759,7 @@ GetForeignTable(Oid relid);
         <para>
     <programlisting>
     List *
    -GetForeignColumnOptions(Oid relid, AttrNumber attnum);
    +GetForeignColumnOptions(Oid relid, AttrNumber attphysnum);
     </programlisting>
     
          This function returns the per-column FDW options for the column with the
    diff --git a/doc/src/sgml/pageinspect.sgml b/doc/src/sgml/pageinspect.sgml
    index d4ee34ee0f..4bfcf3c56d 100644
    --- a/doc/src/sgml/pageinspect.sgml
    +++ b/doc/src/sgml/pageinspect.sgml
    @@ -564,8 +564,8 @@ test=# SELECT * FROM brin_revmap_data(get_raw_page('brinidx', 2)) LIMIT 5;
     <screen>
     test=# SELECT * FROM brin_page_items(get_raw_page('brinidx', 5),
                                          'brinidx')
    -       ORDER BY blknum, attnum LIMIT 6;
    - itemoffset | blknum | attnum | allnulls | hasnulls | placeholder |    value
    +       ORDER BY blknum, attphysnum LIMIT 6;
    + itemoffset | blknum | attphysnum | allnulls | hasnulls | placeholder |    value
     ------------+--------+--------+----------+----------+-------------+--------------
             137 |      0 |      1 | t        | f        | f           |
             137 |      0 |      2 | f        | f        | f           | {1 .. 88}
    diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
    index 65bb0a6a3f..b029355b50 100644
    --- a/doc/src/sgml/ref/psql-ref.sgml
    +++ b/doc/src/sgml/ref/psql-ref.sgml
    @@ -2289,7 +2289,7 @@ Tue Oct 26 21:40:57 CEST 1999
     <programlisting>
     =&gt; <userinput>SELECT format('create index on my_table(%I)', attname)</userinput>
     -&gt; <userinput>FROM pg_attribute</userinput>
    --&gt; <userinput>WHERE attrelid = 'my_table'::regclass AND attnum &gt; 0</userinput>
    +-&gt; <userinput>WHERE attrelid = 'my_table'::regclass AND attphysnum &gt; 0</userinput>
     -&gt; <userinput>ORDER BY attnum</userinput>
     -&gt; <userinput>\gexec</userinput>
     CREATE INDEX
    diff --git a/doc/src/sgml/sources.sgml b/doc/src/sgml/sources.sgml
    index 5186d75d61..b6dab7ff47 100644
    --- a/doc/src/sgml/sources.sgml
    +++ b/doc/src/sgml/sources.sgml
    @@ -326,7 +326,7 @@ ereport(ERROR,
        </listitem>
        <listitem>
         <para>
    -     <function>errtablecol(Relation rel, int attnum)</function> specifies
    +     <function>errtablecol(Relation rel, int attphysnum)</function> specifies
          a column whose name, table name, and schema name should be included as
          auxiliary fields in the error report.
         </para>
    diff --git a/doc/src/sgml/trigger.sgml b/doc/src/sgml/trigger.sgml
    index 04e702a795..6234edbc12 100644
    --- a/doc/src/sgml/trigger.sgml
    +++ b/doc/src/sgml/trigger.sgml
    @@ -803,7 +803,7 @@ typedef struct Trigger
            <para>
             As an example, to determine whether a column with attribute number
             <varname>attnum</varname> (1-based) is a member of this bitmap set,
    -        call <literal>bms_is_member(attnum -
    +        call <literal>bms_is_member(attphysnum -
             FirstLowInvalidHeapAttributeNumber,
             trigdata->tg_updatedcols))</literal>.
            </para>
    diff --git a/doc/src/sgml/xaggr.sgml b/doc/src/sgml/xaggr.sgml
    index bdad8d3dc2..b983149059 100644
    --- a/doc/src/sgml/xaggr.sgml
    +++ b/doc/src/sgml/xaggr.sgml
    @@ -319,7 +319,7 @@ CREATE AGGREGATE array_accum (anycompatible)
     <programlisting>
     SELECT attrelid::regclass, array_accum(attname)
         FROM pg_attribute
    -    WHERE attnum &gt; 0 AND attrelid = 'pg_tablespace'::regclass
    +    WHERE attphysnum &gt; 0 AND attrelid = 'pg_tablespace'::regclass
         GROUP BY attrelid;
     
        attrelid    |              array_accum
    @@ -329,7 +329,7 @@ SELECT attrelid::regclass, array_accum(attname)
     
     SELECT attrelid::regclass, array_accum(atttypid::regtype)
         FROM pg_attribute
    -    WHERE attnum &gt; 0 AND attrelid = 'pg_tablespace'::regclass
    +    WHERE attphysnum &gt; 0 AND attrelid = 'pg_tablespace'::regclass
         GROUP BY attrelid;
     
        attrelid    |        array_accum
    diff --git a/src/backend/access/brin/brin_tuple.c b/src/backend/access/brin/brin_tuple.c
    index c0e2dbd23b..f79840a357 100644
    --- a/src/backend/access/brin/brin_tuple.c
    +++ b/src/backend/access/brin/brin_tuple.c
    @@ -634,7 +634,7 @@ brin_deconstruct_tuple(BrinDesc *brdesc,
     					   char *tp, bits8 *nullbits, bool nulls,
     					   Datum *values, bool *allnulls, bool *hasnulls)
     {
    -	int			attnum;
    +	int			attphysnum;
     	int			stored;
     	TupleDesc	diskdsc;
     	long		off;
    @@ -645,14 +645,14 @@ brin_deconstruct_tuple(BrinDesc *brdesc,
     	 * 1 for a null value (rather than a 1 for a not null value as is the
     	 * att_isnull convention used elsewhere.)  See brin_form_tuple.
     	 */
    -	for (attnum = 0; attnum < brdesc->bd_tupdesc->natts; attnum++)
    +	for (attphysnum = 0; attphysnum < brdesc->bd_tupdesc->natts; attphysnum++)
     	{
     		/*
     		 * the "all nulls" bit means that all values in the page range for
     		 * this column are nulls.  Therefore there are no values in the tuple
     		 * data area.
     		 */
    -		allnulls[attnum] = nulls && !att_isnull(attnum, nullbits);
    +		allnulls[attphysnum] = nulls && !att_isnull(attphysnum, nullbits);
     
     		/*
     		 * the "has nulls" bit means that some tuples have nulls, but others
    @@ -661,8 +661,8 @@ brin_deconstruct_tuple(BrinDesc *brdesc,
     		 *
     		 * The hasnulls bits follow the allnulls bits in the same bitmask.
     		 */
    -		hasnulls[attnum] =
    -			nulls && !att_isnull(brdesc->bd_tupdesc->natts + attnum, nullbits);
    +		hasnulls[attphysnum] =
    +			nulls && !att_isnull(brdesc->bd_tupdesc->natts + attphysnum, nullbits);
     	}
     
     	/*
    @@ -673,18 +673,18 @@ brin_deconstruct_tuple(BrinDesc *brdesc,
     	diskdsc = brtuple_disk_tupdesc(brdesc);
     	stored = 0;
     	off = 0;
    -	for (attnum = 0; attnum < brdesc->bd_tupdesc->natts; attnum++)
    +	for (attphysnum = 0; attphysnum < brdesc->bd_tupdesc->natts; attphysnum++)
     	{
     		int			datumno;
     
    -		if (allnulls[attnum])
    +		if (allnulls[attphysnum])
     		{
    -			stored += brdesc->bd_info[attnum]->oi_nstored;
    +			stored += brdesc->bd_info[attphysnum]->oi_nstored;
     			continue;
     		}
     
     		for (datumno = 0;
    -			 datumno < brdesc->bd_info[attnum]->oi_nstored;
    +			 datumno < brdesc->bd_info[attphysnum]->oi_nstored;
     			 datumno++)
     		{
     			Form_pg_attribute thisatt = TupleDescAttr(diskdsc, stored);
    diff --git a/src/backend/access/common/attmap.c b/src/backend/access/common/attmap.c
    index 896f82a22b..d84b1bcdc4 100644
    --- a/src/backend/access/common/attmap.c
    +++ b/src/backend/access/common/attmap.c
    @@ -231,7 +231,7 @@ build_attrmap_by_name(TupleDesc indesc,
     									   attname,
     									   format_type_be(outdesc->tdtypeid),
     									   format_type_be(indesc->tdtypeid))));
    -				attrMap->attnums[i] = inatt->attnum;
    +				attrMap->attnums[i] = inatt->attphysnum;
     				break;
     			}
     		}
    diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c
    index 503cda46ef..4e61b6b372 100644
    --- a/src/backend/access/common/heaptuple.c
    +++ b/src/backend/access/common/heaptuple.c
    @@ -82,14 +82,14 @@
      */
     Datum
     getmissingattr(TupleDesc tupleDesc,
    -			   int attnum, bool *isnull)
    +			   int attphysnum, bool *isnull)
     {
     	Form_pg_attribute att;
     
    -	Assert(attnum <= tupleDesc->natts);
    -	Assert(attnum > 0);
    +	Assert(attphysnum <= tupleDesc->natts);
    +	Assert(attphysnum > 0);
     
    -	att = TupleDescAttr(tupleDesc, attnum - 1);
    +	att = TupleDescAttr(tupleDesc, attphysnum - 1);
     
     	if (att->atthasmissing)
     	{
    @@ -98,7 +98,7 @@ getmissingattr(TupleDesc tupleDesc,
     		Assert(tupleDesc->constr);
     		Assert(tupleDesc->constr->missing);
     
    -		attrmiss = tupleDesc->constr->missing + (attnum - 1);
    +		attrmiss = tupleDesc->constr->missing + (attphysnum - 1);
     
     		if (attrmiss->am_present)
     		{
    @@ -356,29 +356,29 @@ heap_fill_tuple(TupleDesc tupleDesc,
      * ----------------
      */
     bool
    -heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
    +heap_attisnull(HeapTuple tup, int attphysnum, TupleDesc tupleDesc)
     {
     	/*
     	 * We allow a NULL tupledesc for relations not expected to have missing
     	 * values, such as catalog relations and indexes.
     	 */
    -	Assert(!tupleDesc || attnum <= tupleDesc->natts);
    -	if (attnum > (int) HeapTupleHeaderGetNatts(tup->t_data))
    +	Assert(!tupleDesc || attphysnum <= tupleDesc->natts);
    +	if (attphysnum > (int) HeapTupleHeaderGetNatts(tup->t_data))
     	{
    -		if (tupleDesc && TupleDescAttr(tupleDesc, attnum - 1)->atthasmissing)
    +		if (tupleDesc && TupleDescAttr(tupleDesc, attphysnum - 1)->atthasmissing)
     			return false;
     		else
     			return true;
     	}
     
    -	if (attnum > 0)
    +	if (attphysnum > 0)
     	{
     		if (HeapTupleNoNulls(tup))
     			return false;
    -		return att_isnull(attnum - 1, tup->t_data->t_bits);
    +		return att_isnull(attphysnum - 1, tup->t_data->t_bits);
     	}
     
    -	switch (attnum)
    +	switch (attphysnum)
     	{
     		case TableOidAttributeNumber:
     		case SelfItemPointerAttributeNumber:
    @@ -390,7 +390,7 @@ heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
     			break;
     
     		default:
    -			elog(ERROR, "invalid attnum: %d", attnum);
    +			elog(ERROR, "invalid attphysnum: %d", attphysnum);
     	}
     
     	return false;
    @@ -421,7 +421,7 @@ heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
      */
     Datum
     nocachegetattr(HeapTuple tuple,
    -			   int attnum,
    +			   int attphysnum,
     			   TupleDesc tupleDesc)
     {
     	HeapTupleHeader tup = tuple->t_data;
    @@ -439,7 +439,7 @@ nocachegetattr(HeapTuple tuple,
     	 * ----------------
     	 */
     
    -	attnum--;
    +	attphysnum--;
     
     	if (!HeapTupleNoNulls(tuple))
     	{
    @@ -448,8 +448,8 @@ nocachegetattr(HeapTuple tuple,
     		 *
     		 * check to see if any preceding bits are null...
     		 */
    -		int			byte = attnum >> 3;
    -		int			finalbit = attnum & 0x07;
    +		int			byte = attphysnum >> 3;
    +		int			finalbit = attphysnum & 0x07;
     
     		/* check for nulls "before" final bit of last byte */
     		if ((~bp[byte]) & ((1 << finalbit) - 1))
    @@ -480,7 +480,7 @@ nocachegetattr(HeapTuple tuple,
     		 * If we get here, there are no nulls up to and including the target
     		 * attribute.  If we have a cached offset, we can use it.
     		 */
    -		att = TupleDescAttr(tupleDesc, attnum);
    +		att = TupleDescAttr(tupleDesc, attphysnum);
     		if (att->attcacheoff >= 0)
     			return fetchatt(att, tp + att->attcacheoff);
     
    @@ -493,7 +493,7 @@ nocachegetattr(HeapTuple tuple,
     		{
     			int			j;
     
    -			for (j = 0; j <= attnum; j++)
    +			for (j = 0; j <= attphysnum; j++)
     			{
     				if (TupleDescAttr(tupleDesc, j)->attlen <= 0)
     				{
    @@ -541,9 +541,9 @@ nocachegetattr(HeapTuple tuple,
     			off += att->attlen;
     		}
     
    -		Assert(j > attnum);
    +		Assert(j > attphysnum);
     
    -		off = TupleDescAttr(tupleDesc, attnum)->attcacheoff;
    +		off = TupleDescAttr(tupleDesc, attphysnum)->attcacheoff;
     	}
     	else
     	{
    @@ -601,7 +601,7 @@ nocachegetattr(HeapTuple tuple,
     					att->attcacheoff = off;
     			}
     
    -			if (i == attnum)
    +			if (i == attphysnum)
     				break;
     
     			off = att_addlength_pointer(off, att->attlen, tp + off);
    @@ -611,7 +611,7 @@ nocachegetattr(HeapTuple tuple,
     		}
     	}
     
    -	return fetchatt(TupleDescAttr(tupleDesc, attnum), tp + off);
    +	return fetchatt(TupleDescAttr(tupleDesc, attphysnum), tp + off);
     }
     
     /* ----------------
    @@ -620,11 +620,11 @@ nocachegetattr(HeapTuple tuple,
      *		Fetch the value of a system attribute for a tuple.
      *
      * This is a support routine for the heap_getattr macro.  The macro
    - * has already determined that the attnum refers to a system attribute.
    + * has already determined that the attphysnum refers to a system attribute.
      * ----------------
      */
     Datum
    -heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
    +heap_getsysattr(HeapTuple tup, int attphysnum, TupleDesc tupleDesc, bool *isnull)
     {
     	Datum		result;
     
    @@ -633,7 +633,7 @@ heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
     	/* Currently, no sys attribute ever reads as NULL. */
     	*isnull = false;
     
    -	switch (attnum)
    +	switch (attphysnum)
     	{
     		case SelfItemPointerAttributeNumber:
     			/* pass-by-reference datatype */
    @@ -660,7 +660,7 @@ heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
     			result = ObjectIdGetDatum(tup->t_tableOid);
     			break;
     		default:
    -			elog(ERROR, "invalid attnum: %d", attnum);
    +			elog(ERROR, "invalid attphysnum: %d", attphysnum);
     			result = 0;			/* keep compiler quiet */
     			break;
     	}
    @@ -735,7 +735,7 @@ expand_tuple(HeapTuple *targetHeapTuple,
     			 TupleDesc tupleDesc)
     {
     	AttrMissing *attrmiss = NULL;
    -	int			attnum;
    +	int			attphysnum;
     	int			firstmissingnum;
     	bool		hasNulls = HeapTupleHasNulls(sourceTuple);
     	HeapTupleHeader targetTHeader;
    @@ -790,22 +790,22 @@ expand_tuple(HeapTuple *targetHeapTuple,
     		 * Now walk the missing attributes. If there is a missing value make
     		 * space for it. Otherwise, it's going to be NULL.
     		 */
    -		for (attnum = firstmissingnum;
    -			 attnum < natts;
    -			 attnum++)
    +		for (attphysnum = firstmissingnum;
    +			 attphysnum < natts;
    +			 attphysnum++)
     		{
    -			if (attrmiss[attnum].am_present)
    +			if (attrmiss[attphysnum].am_present)
     			{
    -				Form_pg_attribute att = TupleDescAttr(tupleDesc, attnum);
    +				Form_pg_attribute att = TupleDescAttr(tupleDesc, attphysnum);
     
     				targetDataLen = att_align_datum(targetDataLen,
     												att->attalign,
     												att->attlen,
    -												attrmiss[attnum].am_value);
    +												attrmiss[attphysnum].am_value);
     
     				targetDataLen = att_addlength_pointer(targetDataLen,
     													  att->attlen,
    -													  attrmiss[attnum].am_value);
    +													  attrmiss[attphysnum].am_value);
     			}
     			else
     			{
    @@ -922,19 +922,19 @@ expand_tuple(HeapTuple *targetHeapTuple,
     	targetData += sourceDataLen;
     
     	/* Now fill in the missing values */
    -	for (attnum = sourceNatts; attnum < natts; attnum++)
    +	for (attphysnum = sourceNatts; attphysnum < natts; attphysnum++)
     	{
     
    -		Form_pg_attribute attr = TupleDescAttr(tupleDesc, attnum);
    +		Form_pg_attribute attr = TupleDescAttr(tupleDesc, attphysnum);
     
    -		if (attrmiss && attrmiss[attnum].am_present)
    +		if (attrmiss && attrmiss[attphysnum].am_present)
     		{
     			fill_val(attr,
     					 nullBits ? &nullBits : NULL,
     					 &bitMask,
     					 &targetData,
     					 infoMask,
    -					 attrmiss[attnum].am_value,
    +					 attrmiss[attphysnum].am_value,
     					 false);
     		}
     		else
    @@ -1202,12 +1202,12 @@ heap_modify_tuple_by_cols(HeapTuple tuple,
     
     	for (i = 0; i < nCols; i++)
     	{
    -		int			attnum = replCols[i];
    +		int			attphysnum = replCols[i];
     
    -		if (attnum <= 0 || attnum > numberOfAttributes)
    -			elog(ERROR, "invalid column number %d", attnum);
    -		values[attnum - 1] = replValues[i];
    -		isnull[attnum - 1] = replIsnull[i];
    +		if (attphysnum <= 0 || attphysnum > numberOfAttributes)
    +			elog(ERROR, "invalid column number %d", attphysnum);
    +		values[attphysnum - 1] = replValues[i];
    +		isnull[attphysnum - 1] = replIsnull[i];
     	}
     
     	/*
    @@ -1253,7 +1253,7 @@ heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
     	bool		hasnulls = HeapTupleHasNulls(tuple);
     	int			tdesc_natts = tupleDesc->natts;
     	int			natts;			/* number of atts to extract */
    -	int			attnum;
    +	int			attphysnum;
     	char	   *tp;				/* ptr to tuple data */
     	uint32		off;			/* offset in tuple data */
     	bits8	   *bp = tup->t_bits;	/* ptr to null bitmap in tuple */
    @@ -1272,19 +1272,19 @@ heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
     
     	off = 0;
     
    -	for (attnum = 0; attnum < natts; attnum++)
    +	for (attphysnum = 0; attphysnum < natts; attphysnum++)
     	{
    -		Form_pg_attribute thisatt = TupleDescAttr(tupleDesc, attnum);
    +		Form_pg_attribute thisatt = TupleDescAttr(tupleDesc, attphysnum);
     
    -		if (hasnulls && att_isnull(attnum, bp))
    +		if (hasnulls && att_isnull(attphysnum, bp))
     		{
    -			values[attnum] = (Datum) 0;
    -			isnull[attnum] = true;
    +			values[attphysnum] = (Datum) 0;
    +			isnull[attphysnum] = true;
     			slow = true;		/* can't use attcacheoff anymore */
     			continue;
     		}
     
    -		isnull[attnum] = false;
    +		isnull[attphysnum] = false;
     
     		if (!slow && thisatt->attcacheoff >= 0)
     			off = thisatt->attcacheoff;
    @@ -1315,7 +1315,7 @@ heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
     				thisatt->attcacheoff = off;
     		}
     
    -		values[attnum] = fetchatt(thisatt, tp + off);
    +		values[attphysnum] = fetchatt(thisatt, tp + off);
     
     		off = att_addlength_pointer(off, thisatt->attlen, tp + off);
     
    @@ -1327,8 +1327,8 @@ heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,
     	 * If tuple doesn't have all the atts indicated by tupleDesc, read the
     	 * rest as nulls or missing values as appropriate.
     	 */
    -	for (; attnum < tdesc_natts; attnum++)
    -		values[attnum] = getmissingattr(tupleDesc, attnum + 1, &isnull[attnum]);
    +	for (; attphysnum < tdesc_natts; attphysnum++)
    +		values[attphysnum] = getmissingattr(tupleDesc, attphysnum + 1, &isnull[attphysnum]);
     }
     
     /*
    diff --git a/src/backend/access/common/indextuple.c b/src/backend/access/common/indextuple.c
    index 3065730bae..126bc93e1c 100644
    --- a/src/backend/access/common/indextuple.c
    +++ b/src/backend/access/common/indextuple.c
    @@ -220,7 +220,7 @@ index_form_tuple(TupleDesc tupleDescriptor,
      */
     Datum
     nocache_index_getattr(IndexTuple tup,
    -					  int attnum,
    +					  int attphysnum,
     					  TupleDesc tupleDesc)
     {
     	char	   *tp;				/* ptr to data part of tuple */
    @@ -240,7 +240,7 @@ nocache_index_getattr(IndexTuple tup,
     
     	data_off = IndexInfoFindDataOffset(tup->t_info);
     
    -	attnum--;
    +	attphysnum--;
     
     	if (IndexTupleHasNulls(tup))
     	{
    @@ -257,8 +257,8 @@ nocache_index_getattr(IndexTuple tup,
     		 * Now check to see if any preceding bits are null...
     		 */
     		{
    -			int			byte = attnum >> 3;
    -			int			finalbit = attnum & 0x07;
    +			int			byte = attphysnum >> 3;
    +			int			finalbit = attphysnum & 0x07;
     
     			/* check for nulls "before" final bit of last byte */
     			if ((~bp[byte]) & ((1 << finalbit) - 1))
    @@ -290,7 +290,7 @@ nocache_index_getattr(IndexTuple tup,
     		 * If we get here, there are no nulls up to and including the target
     		 * attribute.  If we have a cached offset, we can use it.
     		 */
    -		att = TupleDescAttr(tupleDesc, attnum);
    +		att = TupleDescAttr(tupleDesc, attphysnum);
     		if (att->attcacheoff >= 0)
     			return fetchatt(att, tp + att->attcacheoff);
     
    @@ -303,7 +303,7 @@ nocache_index_getattr(IndexTuple tup,
     		{
     			int			j;
     
    -			for (j = 0; j <= attnum; j++)
    +			for (j = 0; j <= attphysnum; j++)
     			{
     				if (TupleDescAttr(tupleDesc, j)->attlen <= 0)
     				{
    @@ -351,9 +351,9 @@ nocache_index_getattr(IndexTuple tup,
     			off += att->attlen;
     		}
     
    -		Assert(j > attnum);
    +		Assert(j > attphysnum);
     
    -		off = TupleDescAttr(tupleDesc, attnum)->attcacheoff;
    +		off = TupleDescAttr(tupleDesc, attphysnum)->attcacheoff;
     	}
     	else
     	{
    @@ -411,7 +411,7 @@ nocache_index_getattr(IndexTuple tup,
     					att->attcacheoff = off;
     			}
     
    -			if (i == attnum)
    +			if (i == attphysnum)
     				break;
     
     			off = att_addlength_pointer(off, att->attlen, tp + off);
    @@ -421,7 +421,7 @@ nocache_index_getattr(IndexTuple tup,
     		}
     	}
     
    -	return fetchatt(TupleDescAttr(tupleDesc, attnum), tp + off);
    +	return fetchatt(TupleDescAttr(tupleDesc, attphysnum), tp + off);
     }
     
     /*
    @@ -462,26 +462,26 @@ index_deform_tuple_internal(TupleDesc tupleDescriptor,
     							char *tp, bits8 *bp, int hasnulls)
     {
     	int			natts = tupleDescriptor->natts; /* number of atts to extract */
    -	int			attnum;
    +	int			attphysnum;
     	int			off = 0;		/* offset in tuple data */
     	bool		slow = false;	/* can we use/set attcacheoff? */
     
     	/* Assert to protect callers who allocate fixed-size arrays */
     	Assert(natts <= INDEX_MAX_KEYS);
     
    -	for (attnum = 0; attnum < natts; attnum++)
    +	for (attphysnum = 0; attphysnum < natts; attphysnum++)
     	{
    -		Form_pg_attribute thisatt = TupleDescAttr(tupleDescriptor, attnum);
    +		Form_pg_attribute thisatt = TupleDescAttr(tupleDescriptor, attphysnum);
     
    -		if (hasnulls && att_isnull(attnum, bp))
    +		if (hasnulls && att_isnull(attphysnum, bp))
     		{
    -			values[attnum] = (Datum) 0;
    -			isnull[attnum] = true;
    +			values[attphysnum] = (Datum) 0;
    +			isnull[attphysnum] = true;
     			slow = true;		/* can't use attcacheoff anymore */
     			continue;
     		}
     
    -		isnull[attnum] = false;
    +		isnull[attphysnum] = false;
     
     		if (!slow && thisatt->attcacheoff >= 0)
     			off = thisatt->attcacheoff;
    @@ -512,7 +512,7 @@ index_deform_tuple_internal(TupleDesc tupleDescriptor,
     				thisatt->attcacheoff = off;
     		}
     
    -		values[attnum] = fetchatt(thisatt, tp + off);
    +		values[attphysnum] = fetchatt(thisatt, tp + off);
     
     		off = att_addlength_pointer(off, thisatt->attlen, tp + off);
     
    diff --git a/src/backend/access/common/printsimple.c b/src/backend/access/common/printsimple.c
    index e99aa279f6..8c8b85ed63 100644
    --- a/src/backend/access/common/printsimple.c
    +++ b/src/backend/access/common/printsimple.c
    @@ -41,7 +41,7 @@ printsimple_startup(DestReceiver *self, int operation, TupleDesc tupdesc)
     
     		pq_sendstring(&buf, NameStr(attr->attname));
     		pq_sendint32(&buf, 0);	/* table oid */
    -		pq_sendint16(&buf, 0);	/* attnum */
    +		pq_sendint16(&buf, 0);	/* attphysnum */
     		pq_sendint32(&buf, (int) attr->atttypid);
     		pq_sendint16(&buf, attr->attlen);
     		pq_sendint32(&buf, attr->atttypmod);
    diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
    index 9f41b1e854..409a93ccdf 100644
    --- a/src/backend/access/common/tupdesc.c
    +++ b/src/backend/access/common/tupdesc.c
    @@ -291,7 +291,7 @@ TupleDescCopyEntry(TupleDesc dst, AttrNumber dstAttno,
     	 * by other uses of this function or TupleDescInitEntry.  So we cheat a
     	 * bit to avoid a useless O(N^2) penalty.
     	 */
    -	dstAtt->attnum = dstAttno;
    +	dstAtt->attphysnum = dstAttno;
     	dstAtt->attcacheoff = -1;
     
     	/* since we're not copying constraints or defaults, clear these */
    @@ -416,7 +416,7 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
     
     		/*
     		 * We do not need to check every single field here: we can disregard
    -		 * attrelid and attnum (which were used to place the row in the attrs
    +		 * attrelid and attphysnum (which were used to place the row in the attrs
     		 * array in the first place).  It might look like we could dispense
     		 * with checking attlen/attbyval/attalign, since these are derived
     		 * from atttypid; but in the case of dropped columns we must check
    @@ -619,7 +619,7 @@ TupleDescInitEntry(TupleDesc desc,
     	att->attcacheoff = -1;
     	att->atttypmod = typmod;
     
    -	att->attnum = attributeNumber;
    +	att->attphysnum = attributeNumber;
     	att->attndims = attdim;
     
     	att->attnotnull = false;
    @@ -680,7 +680,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
     	att->attcacheoff = -1;
     	att->atttypmod = typmod;
     
    -	att->attnum = attributeNumber;
    +	att->attphysnum = attributeNumber;
     	att->attndims = attdim;
     
     	att->attnotnull = false;
    @@ -777,7 +777,7 @@ TupleDesc
     BuildDescForRelation(List *schema)
     {
     	int			natts;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	ListCell   *l;
     	TupleDesc	desc;
     	bool		has_not_null;
    @@ -794,7 +794,7 @@ BuildDescForRelation(List *schema)
     	desc = CreateTemplateTupleDesc(natts);
     	has_not_null = false;
     
    -	attnum = 0;
    +	attphysnum = 0;
     
     	foreach(l, schema)
     	{
    @@ -807,7 +807,7 @@ BuildDescForRelation(List *schema)
     		 * the list and have TupleDescInitEntry fill in the attribute
     		 * information we need.
     		 */
    -		attnum++;
    +		attphysnum++;
     
     		attname = entry->colname;
     		typenameTypeIdAndMod(NULL, entry->typeName, &atttypid, &atttypmod);
    @@ -825,12 +825,12 @@ BuildDescForRelation(List *schema)
     					 errmsg("column \"%s\" cannot be declared SETOF",
     							attname)));
     
    -		TupleDescInitEntry(desc, attnum, attname,
    +		TupleDescInitEntry(desc, attphysnum, attname,
     						   atttypid, atttypmod, attdim);
    -		att = TupleDescAttr(desc, attnum - 1);
    +		att = TupleDescAttr(desc, attphysnum - 1);
     
     		/* Override TupleDescInitEntry's settings as requested */
    -		TupleDescInitEntryCollation(desc, attnum, attcollation);
    +		TupleDescInitEntryCollation(desc, attphysnum, attcollation);
     		if (entry->storage)
     			att->attstorage = entry->storage;
     
    @@ -877,7 +877,7 @@ TupleDesc
     BuildDescFromLists(List *names, List *types, List *typmods, List *collations)
     {
     	int			natts;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	ListCell   *l1;
     	ListCell   *l2;
     	ListCell   *l3;
    @@ -894,7 +894,7 @@ BuildDescFromLists(List *names, List *types, List *typmods, List *collations)
     	 */
     	desc = CreateTemplateTupleDesc(natts);
     
    -	attnum = 0;
    +	attphysnum = 0;
     	forfour(l1, names, l2, types, l3, typmods, l4, collations)
     	{
     		char	   *attname = strVal(lfirst(l1));
    @@ -902,10 +902,10 @@ BuildDescFromLists(List *names, List *types, List *typmods, List *collations)
     		int32		atttypmod = lfirst_int(l3);
     		Oid			attcollation = lfirst_oid(l4);
     
    -		attnum++;
    +		attphysnum++;
     
    -		TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
    -		TupleDescInitEntryCollation(desc, attnum, attcollation);
    +		TupleDescInitEntry(desc, attphysnum, attname, atttypid, atttypmod, 0);
    +		TupleDescInitEntryCollation(desc, attphysnum, attcollation);
     	}
     
     	return desc;
    diff --git a/src/backend/access/gin/ginbulk.c b/src/backend/access/gin/ginbulk.c
    index 0d0da44694..2ce4301250 100644
    --- a/src/backend/access/gin/ginbulk.c
    +++ b/src/backend/access/gin/ginbulk.c
    @@ -76,8 +76,8 @@ cmpEntryAccumulator(const RBTNode *a, const RBTNode *b, void *arg)
     	BuildAccumulator *accum = (BuildAccumulator *) arg;
     
     	return ginCompareAttEntries(accum->ginstate,
    -								ea->attnum, ea->key, ea->category,
    -								eb->attnum, eb->key, eb->category);
    +								ea->attphysnum, ea->key, ea->category,
    +								eb->attphysnum, eb->key, eb->category);
     }
     
     /* Allocator function for rbtree.c */
    @@ -125,12 +125,12 @@ ginInitBA(BuildAccumulator *accum)
      * palloc'd space in accum->allocatedMemory.
      */
     static Datum
    -getDatumCopy(BuildAccumulator *accum, OffsetNumber attnum, Datum value)
    +getDatumCopy(BuildAccumulator *accum, OffsetNumber attphysnum, Datum value)
     {
     	Form_pg_attribute att;
     	Datum		res;
     
    -	att = TupleDescAttr(accum->ginstate->origTupdesc, attnum - 1);
    +	att = TupleDescAttr(accum->ginstate->origTupdesc, attphysnum - 1);
     	if (att->attbyval)
     		res = value;
     	else
    @@ -146,7 +146,7 @@ getDatumCopy(BuildAccumulator *accum, OffsetNumber attnum, Datum value)
      */
     static void
     ginInsertBAEntry(BuildAccumulator *accum,
    -				 ItemPointer heapptr, OffsetNumber attnum,
    +				 ItemPointer heapptr, OffsetNumber attphysnum,
     				 Datum key, GinNullCategory category)
     {
     	GinEntryAccumulator eatmp;
    @@ -157,7 +157,7 @@ ginInsertBAEntry(BuildAccumulator *accum,
     	 * For the moment, fill only the fields of eatmp that will be looked at by
     	 * cmpEntryAccumulator or ginCombineData.
     	 */
    -	eatmp.attnum = attnum;
    +	eatmp.attphysnum = attphysnum;
     	eatmp.key = key;
     	eatmp.category = category;
     	/* temporarily set up single-entry itempointer list */
    @@ -173,7 +173,7 @@ ginInsertBAEntry(BuildAccumulator *accum,
     		 * copies of the datum (if it's not null) and itempointer.
     		 */
     		if (category == GIN_CAT_NORM_KEY)
    -			ea->key = getDatumCopy(accum, attnum, key);
    +			ea->key = getDatumCopy(accum, attphysnum, key);
     		ea->maxcount = DEF_NPTR;
     		ea->count = 1;
     		ea->shouldSort = false;
    @@ -208,7 +208,7 @@ ginInsertBAEntry(BuildAccumulator *accum,
      */
     void
     ginInsertBAEntries(BuildAccumulator *accum,
    -				   ItemPointer heapptr, OffsetNumber attnum,
    +				   ItemPointer heapptr, OffsetNumber attphysnum,
     				   Datum *entries, GinNullCategory *categories,
     				   int32 nentries)
     {
    @@ -217,7 +217,7 @@ ginInsertBAEntries(BuildAccumulator *accum,
     	if (nentries <= 0)
     		return;
     
    -	Assert(ItemPointerIsValid(heapptr) && attnum >= FirstOffsetNumber);
    +	Assert(ItemPointerIsValid(heapptr) && attphysnum >= FirstOffsetNumber);
     
     	/*
     	 * step will contain largest power of 2 and <= nentries
    @@ -235,7 +235,7 @@ ginInsertBAEntries(BuildAccumulator *accum,
     		int			i;
     
     		for (i = step - 1; i < nentries && i >= 0; i += step << 1 /* *2 */ )
    -			ginInsertBAEntry(accum, heapptr, attnum,
    +			ginInsertBAEntry(accum, heapptr, attphysnum,
     							 entries[i], categories[i]);
     
     		step >>= 1;				/* /2 */
    @@ -266,7 +266,7 @@ ginBeginBAScan(BuildAccumulator *accum)
      */
     ItemPointerData *
     ginGetBAEntry(BuildAccumulator *accum,
    -			  OffsetNumber *attnum, Datum *key, GinNullCategory *category,
    +			  OffsetNumber *attphysnum, Datum *key, GinNullCategory *category,
     			  uint32 *n)
     {
     	GinEntryAccumulator *entry;
    @@ -277,7 +277,7 @@ ginGetBAEntry(BuildAccumulator *accum,
     	if (entry == NULL)
     		return NULL;			/* no more entries */
     
    -	*attnum = entry->attnum;
    +	*attphysnum = entry->attphysnum;
     	*key = entry->key;
     	*category = entry->category;
     	list = entry->list;
    diff --git a/src/backend/access/gin/ginentrypage.c b/src/backend/access/gin/ginentrypage.c
    index 382f8bb4d6..3b6c2300a3 100644
    --- a/src/backend/access/gin/ginentrypage.c
    +++ b/src/backend/access/gin/ginentrypage.c
    @@ -43,7 +43,7 @@ static void entrySplitPage(GinBtree btree, Buffer origbuf,
      */
     IndexTuple
     GinFormTuple(GinState *ginstate,
    -			 OffsetNumber attnum, Datum key, GinNullCategory category,
    +			 OffsetNumber attphysnum, Datum key, GinNullCategory category,
     			 Pointer data, Size dataSize, int nipd,
     			 bool errorTooBig)
     {
    @@ -60,13 +60,13 @@ GinFormTuple(GinState *ginstate,
     	}
     	else
     	{
    -		datums[0] = UInt16GetDatum(attnum);
    +		datums[0] = UInt16GetDatum(attphysnum);
     		isnull[0] = false;
     		datums[1] = key;
     		isnull[1] = (category != GIN_CAT_NORM_KEY);
     	}
     
    -	itup = index_form_tuple(ginstate->tupdesc[attnum - 1], datums, isnull);
    +	itup = index_form_tuple(ginstate->tupdesc[attphysnum - 1], datums, isnull);
     
     	/*
     	 * Determine and store offset to the posting list, making sure there is
    @@ -160,7 +160,7 @@ GinFormTuple(GinState *ginstate,
      * in *nitems.
      */
     ItemPointer
    -ginReadTuple(GinState *ginstate, OffsetNumber attnum, IndexTuple itup,
    +ginReadTuple(GinState *ginstate, OffsetNumber attphysnum, IndexTuple itup,
     			 int *nitems)
     {
     	Pointer		ptr = GinGetPosting(itup);
    @@ -244,7 +244,7 @@ static bool
     entryIsMoveRight(GinBtree btree, Page page)
     {
     	IndexTuple	itup;
    -	OffsetNumber attnum;
    +	OffsetNumber attphysnum;
     	Datum		key;
     	GinNullCategory category;
     
    @@ -252,12 +252,12 @@ entryIsMoveRight(GinBtree btree, Page page)
     		return false;
     
     	itup = getRightMostTuple(page);
    -	attnum = gintuple_get_attrnum(btree->ginstate, itup);
    +	attphysnum = gintuple_get_attrnum(btree->ginstate, itup);
     	key = gintuple_get_key(btree->ginstate, itup, &category);
     
     	if (ginCompareAttEntries(btree->ginstate,
     							 btree->entryAttnum, btree->entryKey, btree->entryCategory,
    -							 attnum, key, category) > 0)
    +							 attphysnum, key, category) > 0)
     		return true;
     
     	return false;
    @@ -304,18 +304,18 @@ entryLocateEntry(GinBtree btree, GinBtreeStack *stack)
     		}
     		else
     		{
    -			OffsetNumber attnum;
    +			OffsetNumber attphysnum;
     			Datum		key;
     			GinNullCategory category;
     
     			itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, mid));
    -			attnum = gintuple_get_attrnum(btree->ginstate, itup);
    +			attphysnum = gintuple_get_attrnum(btree->ginstate, itup);
     			key = gintuple_get_key(btree->ginstate, itup, &category);
     			result = ginCompareAttEntries(btree->ginstate,
     										  btree->entryAttnum,
     										  btree->entryKey,
     										  btree->entryCategory,
    -										  attnum, key, category);
    +										  attphysnum, key, category);
     		}
     
     		if (result == 0)
    @@ -374,19 +374,19 @@ entryLocateLeafEntry(GinBtree btree, GinBtreeStack *stack)
     	{
     		OffsetNumber mid = low + ((high - low) / 2);
     		IndexTuple	itup;
    -		OffsetNumber attnum;
    +		OffsetNumber attphysnum;
     		Datum		key;
     		GinNullCategory category;
     		int			result;
     
     		itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, mid));
    -		attnum = gintuple_get_attrnum(btree->ginstate, itup);
    +		attphysnum = gintuple_get_attrnum(btree->ginstate, itup);
     		key = gintuple_get_key(btree->ginstate, itup, &category);
     		result = ginCompareAttEntries(btree->ginstate,
     									  btree->entryAttnum,
     									  btree->entryKey,
     									  btree->entryCategory,
    -									  attnum, key, category);
    +									  attphysnum, key, category);
     		if (result == 0)
     		{
     			stack->off = mid;
    @@ -742,7 +742,7 @@ ginEntryFillRoot(GinBtree btree, Page root,
      * other than a faked-up Relation pointer; the key datum is bogus too.
      */
     void
    -ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
    +ginPrepareEntryScan(GinBtree btree, OffsetNumber attphysnum,
     					Datum key, GinNullCategory category,
     					GinState *ginstate)
     {
    @@ -766,7 +766,7 @@ ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
     	btree->fullScan = false;
     	btree->isBuild = false;
     
    -	btree->entryAttnum = attnum;
    +	btree->entryAttnum = attphysnum;
     	btree->entryKey = key;
     	btree->entryCategory = category;
     }
    diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c
    index 7409fdc165..2a50a55fbc 100644
    --- a/src/backend/access/gin/ginfast.c
    +++ b/src/backend/access/gin/ginfast.c
    @@ -473,7 +473,7 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)
     void
     ginHeapTupleFastCollect(GinState *ginstate,
     						GinTupleCollector *collector,
    -						OffsetNumber attnum, Datum value, bool isNull,
    +						OffsetNumber attphysnum, Datum value, bool isNull,
     						ItemPointer ht_ctid)
     {
     	Datum	   *entries;
    @@ -484,7 +484,7 @@ ginHeapTupleFastCollect(GinState *ginstate,
     	/*
     	 * Extract the key values that need to be inserted in the index
     	 */
    -	entries = ginExtractEntries(ginstate, attnum, value, isNull,
    +	entries = ginExtractEntries(ginstate, attphysnum, value, isNull,
     								&nentries, &categories);
     
     	/*
    @@ -527,7 +527,7 @@ ginHeapTupleFastCollect(GinState *ginstate,
     	{
     		IndexTuple	itup;
     
    -		itup = GinFormTuple(ginstate, attnum, entries[i], categories[i],
    +		itup = GinFormTuple(ginstate, attphysnum, entries[i], categories[i],
     							NULL, 0, 0, true);
     		itup->t_tid = *ht_ctid;
     		collector->tuples[collector->ntuples++] = itup;
    @@ -723,7 +723,7 @@ processPendingPage(BuildAccumulator *accum, KeyArray *ka,
     		Datum		curkey;
     		GinNullCategory curcategory;
     
    -		/* Check for change of heap TID or attnum */
    +		/* Check for change of heap TID or attphysnum */
     		curattnum = gintuple_get_attrnum(accum->ginstate, itup);
     
     		if (!ItemPointerIsValid(&heapptr))
    @@ -902,7 +902,7 @@ ginInsertCleanup(GinState *ginstate, bool full_clean,
     			Datum		key;
     			GinNullCategory category;
     			OffsetNumber maxoff,
    -						attnum;
    +						attphysnum;
     
     			/*
     			 * Unlock current page to increase performance. Changes of page
    @@ -919,9 +919,9 @@ ginInsertCleanup(GinState *ginstate, bool full_clean,
     			 */
     			ginBeginBAScan(&accum);
     			while ((list = ginGetBAEntry(&accum,
    -										 &attnum, &key, &category, &nlist)) != NULL)
    +										 &attphysnum, &key, &category, &nlist)) != NULL)
     			{
    -				ginEntryInsert(ginstate, attnum, key, category,
    +				ginEntryInsert(ginstate, attphysnum, key, category,
     							   list, nlist, NULL);
     				vacuum_delay_point();
     			}
    @@ -949,8 +949,8 @@ ginInsertCleanup(GinState *ginstate, bool full_clean,
     
     				ginBeginBAScan(&accum);
     				while ((list = ginGetBAEntry(&accum,
    -											 &attnum, &key, &category, &nlist)) != NULL)
    -					ginEntryInsert(ginstate, attnum, key, category,
    +											 &attphysnum, &key, &category, &nlist)) != NULL)
    +					ginEntryInsert(ginstate, attphysnum, key, category,
     								   list, nlist, NULL);
     			}
     
    diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
    index fc85ba99ac..55f05eb65d 100644
    --- a/src/backend/access/gin/ginget.c
    +++ b/src/backend/access/gin/ginget.c
    @@ -111,9 +111,9 @@ scanPostingTree(Relation index, GinScanEntry scanEntry,
      * 1. Partial-match support: scan from current point until the
      *	  comparePartialFn says we're done.
      * 2. SEARCH_MODE_ALL: scan from current point (which should be first
    - *	  key for the current attnum) until we hit null items or end of attnum
    + *	  key for the current attphysnum) until we hit null items or end of attphysnum
      * 3. SEARCH_MODE_EVERYTHING: scan from current point (which should be first
    - *	  key for the current attnum) until we hit end of attnum
    + *	  key for the current attphysnum) until we hit end of attphysnum
      *
      * Returns true if done, false if it's necessary to restart scan from scratch
      */
    @@ -121,7 +121,7 @@ static bool
     collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack,
     				   GinScanEntry scanEntry, Snapshot snapshot)
     {
    -	OffsetNumber attnum;
    +	OffsetNumber attphysnum;
     	Form_pg_attribute attr;
     
     	/* Initialize empty bitmap result */
    @@ -133,8 +133,8 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack,
     		return true;
     
     	/* Locate tupdesc entry for key column (for attbyval/attlen data) */
    -	attnum = scanEntry->attnum;
    -	attr = TupleDescAttr(btree->ginstate->origTupdesc, attnum - 1);
    +	attphysnum = scanEntry->attphysnum;
    +	attr = TupleDescAttr(btree->ginstate->origTupdesc, attphysnum - 1);
     
     	/*
     	 * Predicate lock entry leaf page, following pages will be locked by
    @@ -162,7 +162,7 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack,
     		/*
     		 * If tuple stores another attribute then stop scan
     		 */
    -		if (gintuple_get_attrnum(btree->ginstate, itup) != attnum)
    +		if (gintuple_get_attrnum(btree->ginstate, itup) != attphysnum)
     			return true;
     
     		/* Safe to fetch attribute value */
    @@ -189,8 +189,8 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack,
     			 * case cmp < 0 => not match and continue scan
     			 *----------
     			 */
    -			cmp = DatumGetInt32(FunctionCall4Coll(&btree->ginstate->comparePartialFn[attnum - 1],
    -												  btree->ginstate->supportCollation[attnum - 1],
    +			cmp = DatumGetInt32(FunctionCall4Coll(&btree->ginstate->comparePartialFn[attphysnum - 1],
    +												  btree->ginstate->supportCollation[attphysnum - 1],
     												  scanEntry->queryKey,
     												  idatum,
     												  UInt16GetDatum(scanEntry->strategy),
    @@ -209,7 +209,7 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack,
     			/*
     			 * In ALL mode, we are not interested in null items, so we can
     			 * stop if we get to a null-item placeholder (which will be the
    -			 * last entry for a given attnum).  We do want to include NULL_KEY
    +			 * last entry for a given attphysnum).  We do want to include NULL_KEY
     			 * and EMPTY_ITEM entries, though.
     			 */
     			if (icategory == GIN_CAT_NULL_ITEM)
    @@ -274,7 +274,7 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack,
     				page = BufferGetPage(stack->buffer);
     				itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, stack->off));
     
    -				if (gintuple_get_attrnum(btree->ginstate, itup) == attnum)
    +				if (gintuple_get_attrnum(btree->ginstate, itup) == attphysnum)
     				{
     					Datum		newDatum;
     					GinNullCategory newCategory;
    @@ -282,7 +282,7 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack,
     					newDatum = gintuple_get_key(btree->ginstate, itup,
     												&newCategory);
     
    -					if (ginCompareEntries(btree->ginstate, attnum,
    +					if (ginCompareEntries(btree->ginstate, attphysnum,
     										  newDatum, newCategory,
     										  idatum, icategory) == 0)
     						break;	/* Found! */
    @@ -299,7 +299,7 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack,
     			ItemPointer ipd;
     			int			nipd;
     
    -			ipd = ginReadTuple(btree->ginstate, scanEntry->attnum, itup, &nipd);
    +			ipd = ginReadTuple(btree->ginstate, scanEntry->attphysnum, itup, &nipd);
     			tbm_add_tuples(scanEntry->matchBitmap, ipd, nipd, false);
     			scanEntry->predictNumberResult += GinGetNPosting(itup);
     			pfree(ipd);
    @@ -340,7 +340,7 @@ restartScanEntry:
     	 * we should find entry, and begin scan of posting tree or just store
     	 * posting list in memory
     	 */
    -	ginPrepareEntryScan(&btreeEntry, entry->attnum,
    +	ginPrepareEntryScan(&btreeEntry, entry->attphysnum,
     						entry->queryKey, entry->queryCategory,
     						ginstate);
     	stackEntry = ginFindLeafPage(&btreeEntry, true, false, snapshot);
    @@ -457,7 +457,7 @@ restartScanEntry:
     							  snapshot);
     			if (GinGetNPosting(itup) > 0)
     			{
    -				entry->list = ginReadTuple(ginstate, entry->attnum, itup,
    +				entry->list = ginReadTuple(ginstate, entry->attphysnum, itup,
     										   &entry->nlist);
     				entry->predictNumberResult = entry->nlist;
     
    @@ -1553,7 +1553,7 @@ matchPartialInPendingList(GinState *ginstate, Page page,
     	{
     		itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off));
     
    -		if (gintuple_get_attrnum(ginstate, itup) != entry->attnum)
    +		if (gintuple_get_attrnum(ginstate, itup) != entry->attphysnum)
     			return false;
     
     		if (datumExtracted[off - 1] == false)
    @@ -1574,8 +1574,8 @@ matchPartialInPendingList(GinState *ginstate, Page page,
     		 * case cmp < 0 => not match and continue scan
     		 *----------
     		 */
    -		cmp = DatumGetInt32(FunctionCall4Coll(&ginstate->comparePartialFn[entry->attnum - 1],
    -											  ginstate->supportCollation[entry->attnum - 1],
    +		cmp = DatumGetInt32(FunctionCall4Coll(&ginstate->comparePartialFn[entry->attphysnum - 1],
    +											  ginstate->supportCollation[entry->attphysnum - 1],
     											  entry->queryKey,
     											  datum[off - 1],
     											  UInt16GetDatum(entry->strategy),
    @@ -1658,7 +1658,7 @@ collectMatchesForHeapRow(IndexScanDesc scan, pendingPosition *pos)
     
     				/*
     				 * Interesting tuples are from pos->firstOffset to
    -				 * pos->lastOffset and they are ordered by (attnum, Datum) as
    +				 * pos->lastOffset and they are ordered by (attphysnum, Datum) as
     				 * it's done in entry tree.  So we can use binary search to
     				 * avoid linear scanning.
     				 */
    @@ -1672,12 +1672,12 @@ collectMatchesForHeapRow(IndexScanDesc scan, pendingPosition *pos)
     
     					attrnum = gintuple_get_attrnum(&so->ginstate, itup);
     
    -					if (key->attnum < attrnum)
    +					if (key->attphysnum < attrnum)
     					{
     						StopHigh = StopMiddle;
     						continue;
     					}
    -					if (key->attnum > attrnum)
    +					if (key->attphysnum > attrnum)
     					{
     						StopLow = StopMiddle + 1;
     						continue;
    @@ -1711,7 +1711,7 @@ collectMatchesForHeapRow(IndexScanDesc scan, pendingPosition *pos)
     					else
     					{
     						res = ginCompareEntries(&so->ginstate,
    -												entry->attnum,
    +												entry->attphysnum,
     												entry->queryKey,
     												entry->queryCategory,
     												datum[StopMiddle - 1],
    diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
    index ea1c4184fb..a25ee278a5 100644
    --- a/src/backend/access/gin/gininsert.c
    +++ b/src/backend/access/gin/gininsert.c
    @@ -51,7 +51,7 @@ addItemPointersToLeafTuple(GinState *ginstate,
     						   ItemPointerData *items, uint32 nitem,
     						   GinStatsData *buildStats, Buffer buffer)
     {
    -	OffsetNumber attnum;
    +	OffsetNumber attphysnum;
     	Datum		key;
     	GinNullCategory category;
     	IndexTuple	res;
    @@ -63,11 +63,11 @@ addItemPointersToLeafTuple(GinState *ginstate,
     
     	Assert(!GinIsPostingTree(old));
     
    -	attnum = gintuple_get_attrnum(ginstate, old);
    +	attphysnum = gintuple_get_attrnum(ginstate, old);
     	key = gintuple_get_key(ginstate, old, &category);
     
     	/* merge the old and new posting lists */
    -	oldItems = ginReadTuple(ginstate, attnum, old, &oldNPosting);
    +	oldItems = ginReadTuple(ginstate, attphysnum, old, &oldNPosting);
     
     	newItems = ginMergeItemPointers(items, nitem,
     									oldItems, oldNPosting,
    @@ -80,7 +80,7 @@ addItemPointersToLeafTuple(GinState *ginstate,
     	pfree(newItems);
     	if (compressedList)
     	{
    -		res = GinFormTuple(ginstate, attnum, key, category,
    +		res = GinFormTuple(ginstate, attphysnum, key, category,
     						   (char *) compressedList,
     						   SizeOfGinPostingList(compressedList),
     						   newNPosting,
    @@ -109,7 +109,7 @@ addItemPointersToLeafTuple(GinState *ginstate,
     							  buildStats);
     
     		/* And build a new posting-tree-only result tuple */
    -		res = GinFormTuple(ginstate, attnum, key, category, NULL, 0, 0, true);
    +		res = GinFormTuple(ginstate, attphysnum, key, category, NULL, 0, 0, true);
     		GinSetPostingTree(res, postingRoot);
     	}
     	pfree(oldItems);
    @@ -127,7 +127,7 @@ addItemPointersToLeafTuple(GinState *ginstate,
      */
     static IndexTuple
     buildFreshLeafTuple(GinState *ginstate,
    -					OffsetNumber attnum, Datum key, GinNullCategory category,
    +					OffsetNumber attphysnum, Datum key, GinNullCategory category,
     					ItemPointerData *items, uint32 nitem,
     					GinStatsData *buildStats, Buffer buffer)
     {
    @@ -138,7 +138,7 @@ buildFreshLeafTuple(GinState *ginstate,
     	compressedList = ginCompressPostingList(items, nitem, GinMaxItemSize, NULL);
     	if (compressedList)
     	{
    -		res = GinFormTuple(ginstate, attnum, key, category,
    +		res = GinFormTuple(ginstate, attphysnum, key, category,
     						   (char *) compressedList,
     						   SizeOfGinPostingList(compressedList),
     						   nitem, false);
    @@ -153,7 +153,7 @@ buildFreshLeafTuple(GinState *ginstate,
     		 * Build posting-tree-only result tuple.  We do this first so as to
     		 * fail quickly if the key is too big.
     		 */
    -		res = GinFormTuple(ginstate, attnum, key, category, NULL, 0, 0, true);
    +		res = GinFormTuple(ginstate, attphysnum, key, category, NULL, 0, 0, true);
     
     		/*
     		 * Initialize a new posting tree with the TIDs.
    @@ -177,7 +177,7 @@ buildFreshLeafTuple(GinState *ginstate,
      */
     void
     ginEntryInsert(GinState *ginstate,
    -			   OffsetNumber attnum, Datum key, GinNullCategory category,
    +			   OffsetNumber attphysnum, Datum key, GinNullCategory category,
     			   ItemPointerData *items, uint32 nitem,
     			   GinStatsData *buildStats)
     {
    @@ -189,7 +189,7 @@ ginEntryInsert(GinState *ginstate,
     
     	insertdata.isDelete = false;
     
    -	ginPrepareEntryScan(&btree, attnum, key, category, ginstate);
    +	ginPrepareEntryScan(&btree, attphysnum, key, category, ginstate);
     	btree.isBuild = (buildStats != NULL);
     
     	stack = ginFindLeafPage(&btree, false, false, NULL);
    @@ -229,7 +229,7 @@ ginEntryInsert(GinState *ginstate,
     		CheckForSerializableConflictIn(ginstate->index, NULL,
     									   BufferGetBlockNumber(stack->buffer));
     		/* no match, so construct a new leaf entry */
    -		itup = buildFreshLeafTuple(ginstate, attnum, key, category,
    +		itup = buildFreshLeafTuple(ginstate, attphysnum, key, category,
     								   items, nitem, buildStats, stack->buffer);
     
     		/*
    @@ -253,7 +253,7 @@ ginEntryInsert(GinState *ginstate,
      * This function is used only during initial index creation.
      */
     static void
    -ginHeapTupleBulkInsert(GinBuildState *buildstate, OffsetNumber attnum,
    +ginHeapTupleBulkInsert(GinBuildState *buildstate, OffsetNumber attphysnum,
     					   Datum value, bool isNull,
     					   ItemPointer heapptr)
     {
    @@ -263,12 +263,12 @@ ginHeapTupleBulkInsert(GinBuildState *buildstate, OffsetNumber attnum,
     	MemoryContext oldCtx;
     
     	oldCtx = MemoryContextSwitchTo(buildstate->funcCtx);
    -	entries = ginExtractEntries(buildstate->accum.ginstate, attnum,
    +	entries = ginExtractEntries(buildstate->accum.ginstate, attphysnum,
     								value, isNull,
     								&nentries, &categories);
     	MemoryContextSwitchTo(oldCtx);
     
    -	ginInsertBAEntries(&buildstate->accum, heapptr, attnum,
    +	ginInsertBAEntries(&buildstate->accum, heapptr, attphysnum,
     					   entries, categories, nentries);
     
     	buildstate->indtuples += nentries;
    @@ -297,15 +297,15 @@ ginBuildCallback(Relation index, ItemPointer tid, Datum *values,
     		Datum		key;
     		GinNullCategory category;
     		uint32		nlist;
    -		OffsetNumber attnum;
    +		OffsetNumber attphysnum;
     
     		ginBeginBAScan(&buildstate->accum);
     		while ((list = ginGetBAEntry(&buildstate->accum,
    -									 &attnum, &key, &category, &nlist)) != NULL)
    +									 &attphysnum, &key, &category, &nlist)) != NULL)
     		{
     			/* there could be many entries, so be willing to abort here */
     			CHECK_FOR_INTERRUPTS();
    -			ginEntryInsert(&buildstate->ginstate, attnum, key, category,
    +			ginEntryInsert(&buildstate->ginstate, attphysnum, key, category,
     						   list, nlist, &buildstate->buildStats);
     		}
     
    @@ -329,7 +329,7 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
     	GinNullCategory category;
     	uint32		nlist;
     	MemoryContext oldCtx;
    -	OffsetNumber attnum;
    +	OffsetNumber attphysnum;
     
     	if (RelationGetNumberOfBlocks(index) != 0)
     		elog(ERROR, "index \"%s\" already contains data",
    @@ -390,11 +390,11 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
     	oldCtx = MemoryContextSwitchTo(buildstate.tmpCtx);
     	ginBeginBAScan(&buildstate.accum);
     	while ((list = ginGetBAEntry(&buildstate.accum,
    -								 &attnum, &key, &category, &nlist)) != NULL)
    +								 &attphysnum, &key, &category, &nlist)) != NULL)
     	{
     		/* there could be many entries, so be willing to abort here */
     		CHECK_FOR_INTERRUPTS();
    -		ginEntryInsert(&buildstate.ginstate, attnum, key, category,
    +		ginEntryInsert(&buildstate.ginstate, attphysnum, key, category,
     					   list, nlist, &buildstate.buildStats);
     	}
     	MemoryContextSwitchTo(oldCtx);
    @@ -467,7 +467,7 @@ ginbuildempty(Relation index)
      * (non-fast-update) insertion
      */
     static void
    -ginHeapTupleInsert(GinState *ginstate, OffsetNumber attnum,
    +ginHeapTupleInsert(GinState *ginstate, OffsetNumber attphysnum,
     				   Datum value, bool isNull,
     				   ItemPointer item)
     {
    @@ -476,11 +476,11 @@ ginHeapTupleInsert(GinState *ginstate, OffsetNumber attnum,
     	int32		i,
     				nentries;
     
    -	entries = ginExtractEntries(ginstate, attnum, value, isNull,
    +	entries = ginExtractEntries(ginstate, attphysnum, value, isNull,
     								&nentries, &categories);
     
     	for (i = 0; i < nentries; i++)
    -		ginEntryInsert(ginstate, attnum, entries[i], categories[i],
    +		ginEntryInsert(ginstate, attphysnum, entries[i], categories[i],
     					   item, 1, NULL);
     }
     
    diff --git a/src/backend/access/gin/ginlogic.c b/src/backend/access/gin/ginlogic.c
    index c38c27fbae..442c338631 100644
    --- a/src/backend/access/gin/ginlogic.c
    +++ b/src/backend/access/gin/ginlogic.c
    @@ -229,16 +229,16 @@ ginInitConsistentFunction(GinState *ginstate, GinScanKey key)
     	}
     	else
     	{
    -		key->consistentFmgrInfo = &ginstate->consistentFn[key->attnum - 1];
    -		key->triConsistentFmgrInfo = &ginstate->triConsistentFn[key->attnum - 1];
    -		key->collation = ginstate->supportCollation[key->attnum - 1];
    +		key->consistentFmgrInfo = &ginstate->consistentFn[key->attphysnum - 1];
    +		key->triConsistentFmgrInfo = &ginstate->triConsistentFn[key->attphysnum - 1];
    +		key->collation = ginstate->supportCollation[key->attphysnum - 1];
     
    -		if (OidIsValid(ginstate->consistentFn[key->attnum - 1].fn_oid))
    +		if (OidIsValid(ginstate->consistentFn[key->attphysnum - 1].fn_oid))
     			key->boolConsistentFn = directBoolConsistentFn;
     		else
     			key->boolConsistentFn = shimBoolConsistentFn;
     
    -		if (OidIsValid(ginstate->triConsistentFn[key->attnum - 1].fn_oid))
    +		if (OidIsValid(ginstate->triConsistentFn[key->attphysnum - 1].fn_oid))
     			key->triConsistentFn = directTriConsistentFn;
     		else
     			key->triConsistentFn = shimTriConsistentFn;
    diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c
    index b776d04459..8bf5cfe7f7 100644
    --- a/src/backend/access/gin/ginscan.c
    +++ b/src/backend/access/gin/ginscan.c
    @@ -54,7 +54,7 @@ ginbeginscan(Relation rel, int nkeys, int norderbys)
      * in which case just return it
      */
     static GinScanEntry
    -ginFillScanEntry(GinScanOpaque so, OffsetNumber attnum,
    +ginFillScanEntry(GinScanOpaque so, OffsetNumber attphysnum,
     				 StrategyNumber strategy, int32 searchMode,
     				 Datum queryKey, GinNullCategory queryCategory,
     				 bool isPartialMatch, Pointer extra_data)
    @@ -79,8 +79,8 @@ ginFillScanEntry(GinScanOpaque so, OffsetNumber attnum,
     				prevEntry->isPartialMatch == isPartialMatch &&
     				prevEntry->strategy == strategy &&
     				prevEntry->searchMode == searchMode &&
    -				prevEntry->attnum == attnum &&
    -				ginCompareEntries(ginstate, attnum,
    +				prevEntry->attphysnum == attphysnum &&
    +				ginCompareEntries(ginstate, attphysnum,
     								  prevEntry->queryKey,
     								  prevEntry->queryCategory,
     								  queryKey,
    @@ -100,7 +100,7 @@ ginFillScanEntry(GinScanOpaque so, OffsetNumber attnum,
     	scanEntry->extra_data = extra_data;
     	scanEntry->strategy = strategy;
     	scanEntry->searchMode = searchMode;
    -	scanEntry->attnum = attnum;
    +	scanEntry->attphysnum = attphysnum;
     
     	scanEntry->buffer = InvalidBuffer;
     	ItemPointerSetMin(&scanEntry->curItem);
    @@ -140,7 +140,7 @@ ginScanKeyAddHiddenEntry(GinScanOpaque so, GinScanKey key,
     	int			i = key->nentries++;
     
     	/* strategy is of no interest because this is not a partial-match item */
    -	key->scanEntry[i] = ginFillScanEntry(so, key->attnum,
    +	key->scanEntry[i] = ginFillScanEntry(so, key->attphysnum,
     										 InvalidStrategy, key->searchMode,
     										 (Datum) 0, queryCategory,
     										 false, NULL);
    @@ -150,7 +150,7 @@ ginScanKeyAddHiddenEntry(GinScanOpaque so, GinScanKey key,
      * Initialize the next GinScanKey using the output from the extractQueryFn
      */
     static void
    -ginFillScanKey(GinScanOpaque so, OffsetNumber attnum,
    +ginFillScanKey(GinScanOpaque so, OffsetNumber attphysnum,
     			   StrategyNumber strategy, int32 searchMode,
     			   Datum query, uint32 nQueryValues,
     			   Datum *queryValues, GinNullCategory *queryCategories,
    @@ -175,7 +175,7 @@ ginFillScanKey(GinScanOpaque so, OffsetNumber attnum,
     	key->extra_data = extra_data;
     	key->strategy = strategy;
     	key->searchMode = searchMode;
    -	key->attnum = attnum;
    +	key->attphysnum = attphysnum;
     
     	/*
     	 * Initially, scan keys of GIN_SEARCH_MODE_ALL mode are marked
    @@ -205,11 +205,11 @@ ginFillScanKey(GinScanOpaque so, OffsetNumber attnum,
     		queryKey = queryValues[i];
     		queryCategory = queryCategories[i];
     		isPartialMatch =
    -			(ginstate->canPartialMatch[attnum - 1] && partial_matches)
    +			(ginstate->canPartialMatch[attphysnum - 1] && partial_matches)
     			? partial_matches[i] : false;
     		this_extra = (extra_data) ? extra_data[i] : NULL;
     
    -		key->scanEntry[i] = ginFillScanEntry(so, attnum,
    +		key->scanEntry[i] = ginFillScanEntry(so, attphysnum,
     											 strategy, searchMode,
     											 queryKey, queryCategory,
     											 isPartialMatch, this_extra);
    @@ -394,11 +394,11 @@ ginNewScanKey(IndexScanDesc scan)
     		if (key->searchMode != GIN_SEARCH_MODE_ALL)
     			continue;
     
    -		if (!attrHasNormalScan[key->attnum - 1])
    +		if (!attrHasNormalScan[key->attphysnum - 1])
     		{
     			key->excludeOnly = false;
     			ginScanKeyAddHiddenEntry(so, key, GIN_CAT_EMPTY_QUERY);
    -			attrHasNormalScan[key->attnum - 1] = true;
    +			attrHasNormalScan[key->attphysnum - 1] = true;
     		}
     	}
     
    diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
    index 20f470648b..caca0c4de4 100644
    --- a/src/backend/access/gin/ginutil.c
    +++ b/src/backend/access/gin/ginutil.c
    @@ -391,7 +391,7 @@ GinInitMetabuffer(Buffer b)
      * Compare two keys of the same index column
      */
     int
    -ginCompareEntries(GinState *ginstate, OffsetNumber attnum,
    +ginCompareEntries(GinState *ginstate, OffsetNumber attphysnum,
     				  Datum a, GinNullCategory categorya,
     				  Datum b, GinNullCategory categoryb)
     {
    @@ -404,8 +404,8 @@ ginCompareEntries(GinState *ginstate, OffsetNumber attnum,
     		return 0;
     
     	/* both not null, so safe to call the compareFn */
    -	return DatumGetInt32(FunctionCall2Coll(&ginstate->compareFn[attnum - 1],
    -										   ginstate->supportCollation[attnum - 1],
    +	return DatumGetInt32(FunctionCall2Coll(&ginstate->compareFn[attphysnum - 1],
    +										   ginstate->supportCollation[attphysnum - 1],
     										   a, b));
     }
     
    @@ -486,7 +486,7 @@ cmpEntries(const void *a, const void *b, void *arg)
      * This avoids generating redundant index entries.
      */
     Datum *
    -ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
    +ginExtractEntries(GinState *ginstate, OffsetNumber attphysnum,
     				  Datum value, bool isNull,
     				  int32 *nentries, GinNullCategory **categories)
     {
    @@ -511,8 +511,8 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
     	/* OK, call the opclass's extractValueFn */
     	nullFlags = NULL;			/* in case extractValue doesn't set it */
     	entries = (Datum *)
    -		DatumGetPointer(FunctionCall3Coll(&ginstate->extractValueFn[attnum - 1],
    -										  ginstate->supportCollation[attnum - 1],
    +		DatumGetPointer(FunctionCall3Coll(&ginstate->extractValueFn[attphysnum - 1],
    +										  ginstate->supportCollation[attphysnum - 1],
     										  value,
     										  PointerGetDatum(nentries),
     										  PointerGetDatum(&nullFlags)));
    @@ -556,8 +556,8 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
     			keydata[i].isnull = nullFlags[i];
     		}
     
    -		arg.cmpDatumFunc = &ginstate->compareFn[attnum - 1];
    -		arg.collation = ginstate->supportCollation[attnum - 1];
    +		arg.cmpDatumFunc = &ginstate->compareFn[attphysnum - 1];
    +		arg.collation = ginstate->supportCollation[attphysnum - 1];
     		arg.haveDups = false;
     		qsort_arg(keydata, *nentries, sizeof(keyEntryData),
     				  cmpEntries, (void *) &arg);
    diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c
    index b4fa5f6bf8..67293adee3 100644
    --- a/src/backend/access/gin/ginvacuum.c
    +++ b/src/backend/access/gin/ginvacuum.c
    @@ -506,7 +506,7 @@ ginVacuumEntryPage(GinVacuumState *gvs, Buffer buffer, BlockNumber *roots, uint3
     			/* If any item pointers were removed, recreate the tuple. */
     			if (items)
     			{
    -				OffsetNumber attnum;
    +				OffsetNumber attphysnum;
     				Datum		key;
     				GinNullCategory category;
     				GinPostingList *plist;
    @@ -539,9 +539,9 @@ ginVacuumEntryPage(GinVacuumState *gvs, Buffer buffer, BlockNumber *roots, uint3
     					itup = (IndexTuple) PageGetItem(tmppage, PageGetItemId(tmppage, i));
     				}
     
    -				attnum = gintuple_get_attrnum(&gvs->ginstate, itup);
    +				attphysnum = gintuple_get_attrnum(&gvs->ginstate, itup);
     				key = gintuple_get_key(&gvs->ginstate, itup, &category);
    -				itup = GinFormTuple(&gvs->ginstate, attnum, key, category,
    +				itup = GinFormTuple(&gvs->ginstate, attphysnum, key, category,
     									(char *) plist, plistsize,
     									nitems, true);
     				if (plist)
    diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c
    index 98af5347b9..46cce23c46 100644
    --- a/src/backend/access/index/genam.c
    +++ b/src/backend/access/index/genam.c
    @@ -216,16 +216,16 @@ BuildIndexValueDescription(Relation indexRelation,
     		 */
     		for (keyno = 0; keyno < indnkeyatts; keyno++)
     		{
    -			AttrNumber	attnum = idxrec->indkey.values[keyno];
    +			AttrNumber	attphysnum = idxrec->indkey.values[keyno];
     
     			/*
    -			 * Note that if attnum == InvalidAttrNumber, then this is an index
    +			 * Note that if attphysnum == InvalidAttrNumber, then this is an index
     			 * based on an expression and we return no detail rather than try
     			 * to figure out what column(s) the expression includes and if the
     			 * user has SELECT rights on them.
     			 */
    -			if (attnum == InvalidAttrNumber ||
    -				pg_attribute_aclcheck(indrelid, attnum, GetUserId(),
    +			if (attphysnum == InvalidAttrNumber ||
    +				pg_attribute_aclcheck(indrelid, attphysnum, GetUserId(),
     									  ACL_SELECT) != ACLCHECK_OK)
     			{
     				/* No access, so clean up and return */
    diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
    index fe80b8b0ba..e6e8ddafea 100644
    --- a/src/backend/access/index/indexam.c
    +++ b/src/backend/access/index/indexam.c
    @@ -767,7 +767,7 @@ index_can_return(Relation indexRelation, int attno)
      */
     RegProcedure
     index_getprocid(Relation irel,
    -				AttrNumber attnum,
    +				AttrNumber attphysnum,
     				uint16 procnum)
     {
     	RegProcedure *loc;
    @@ -778,7 +778,7 @@ index_getprocid(Relation irel,
     
     	Assert(procnum > 0 && procnum <= (uint16) nproc);
     
    -	procindex = (nproc * (attnum - 1)) + (procnum - 1);
    +	procindex = (nproc * (attphysnum - 1)) + (procnum - 1);
     
     	loc = irel->rd_support;
     
    @@ -801,7 +801,7 @@ index_getprocid(Relation irel,
      */
     FmgrInfo *
     index_getprocinfo(Relation irel,
    -				  AttrNumber attnum,
    +				  AttrNumber attphysnum,
     				  uint16 procnum)
     {
     	FmgrInfo   *locinfo;
    @@ -814,7 +814,7 @@ index_getprocinfo(Relation irel,
     
     	Assert(procnum > 0 && procnum <= (uint16) nproc);
     
    -	procindex = (nproc * (attnum - 1)) + (procnum - 1);
    +	procindex = (nproc * (attphysnum - 1)) + (procnum - 1);
     
     	locinfo = irel->rd_supportinfo;
     
    @@ -840,7 +840,7 @@ index_getprocinfo(Relation irel,
     		 */
     		if (!RegProcedureIsValid(procId))
     			elog(ERROR, "missing support function %d for attribute %d of index \"%s\"",
    -				 procnum, attnum, RelationGetRelationName(irel));
    +				 procnum, attphysnum, RelationGetRelationName(irel));
     
     		fmgr_info_cxt(procId, locinfo, irel->rd_indexcxt);
     
    @@ -850,7 +850,7 @@ index_getprocinfo(Relation irel,
     			bytea	  **attoptions = RelationGetIndexAttOptions(irel, false);
     			MemoryContext oldcxt = MemoryContextSwitchTo(irel->rd_indexcxt);
     
    -			set_fn_opclass_options(locinfo, attoptions[attnum - 1]);
    +			set_fn_opclass_options(locinfo, attoptions[attphysnum - 1]);
     
     			MemoryContextSwitchTo(oldcxt);
     		}
    @@ -936,7 +936,7 @@ index_store_float8_orderby_distances(IndexScanDesc scan, Oid *orderByTypes,
      * ----------------
      */
     bytea *
    -index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions,
    +index_opclass_options(Relation indrel, AttrNumber attphysnum, Datum attoptions,
     					  bool validate)
     {
     	int			amoptsprocnum = indrel->rd_indam->amoptsprocnum;
    @@ -946,7 +946,7 @@ index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions,
     
     	/* fetch options support procedure if specified */
     	if (amoptsprocnum != 0)
    -		procid = index_getprocid(indrel, attnum, amoptsprocnum);
    +		procid = index_getprocid(indrel, attphysnum, amoptsprocnum);
     
     	if (!OidIsValid(procid))
     	{
    @@ -966,7 +966,7 @@ index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions,
     										Anum_pg_index_indclass, &isnull);
     		Assert(!isnull);
     		indclass = (oidvector *) DatumGetPointer(indclassDatum);
    -		opclass = indclass->values[attnum - 1];
    +		opclass = indclass->values[attphysnum - 1];
     
     		ereport(ERROR,
     				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    @@ -976,7 +976,7 @@ index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions,
     
     	init_local_reloptions(&relopts, 0);
     
    -	procinfo = index_getprocinfo(indrel, attnum, amoptsprocnum);
    +	procinfo = index_getprocinfo(indrel, attphysnum, amoptsprocnum);
     
     	(void) FunctionCall1(procinfo, PointerGetDatum(&relopts));
     
    diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
    index ff260c393a..9c5f50f84f 100644
    --- a/src/backend/access/nbtree/nbtutils.c
    +++ b/src/backend/access/nbtree/nbtutils.c
    @@ -2365,15 +2365,15 @@ _bt_keep_natts(Relation rel, IndexTuple lastleft, IndexTuple firstright,
     
     	scankey = itup_key->scankeys;
     	keepnatts = 1;
    -	for (int attnum = 1; attnum <= nkeyatts; attnum++, scankey++)
    +	for (int attphysnum = 1; attphysnum <= nkeyatts; attphysnum++, scankey++)
     	{
     		Datum		datum1,
     					datum2;
     		bool		isNull1,
     					isNull2;
     
    -		datum1 = index_getattr(lastleft, attnum, itupdesc, &isNull1);
    -		datum2 = index_getattr(firstright, attnum, itupdesc, &isNull2);
    +		datum1 = index_getattr(lastleft, attphysnum, itupdesc, &isNull1);
    +		datum2 = index_getattr(firstright, attphysnum, itupdesc, &isNull2);
     
     		if (isNull1 != isNull2)
     			break;
    @@ -2428,7 +2428,7 @@ _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, IndexTuple firstright)
     	int			keepnatts;
     
     	keepnatts = 1;
    -	for (int attnum = 1; attnum <= keysz; attnum++)
    +	for (int attphysnum = 1; attphysnum <= keysz; attphysnum++)
     	{
     		Datum		datum1,
     					datum2;
    @@ -2436,9 +2436,9 @@ _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, IndexTuple firstright)
     					isNull2;
     		Form_pg_attribute att;
     
    -		datum1 = index_getattr(lastleft, attnum, itupdesc, &isNull1);
    -		datum2 = index_getattr(firstright, attnum, itupdesc, &isNull2);
    -		att = TupleDescAttr(itupdesc, attnum - 1);
    +		datum1 = index_getattr(lastleft, attphysnum, itupdesc, &isNull1);
    +		datum2 = index_getattr(firstright, attphysnum, itupdesc, &isNull2);
    +		att = TupleDescAttr(itupdesc, attphysnum - 1);
     
     		if (isNull1 != isNull2)
     			break;
    diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
    index 9a610d41ad..37107dc12b 100644
    --- a/src/backend/bootstrap/bootstrap.c
    +++ b/src/backend/bootstrap/bootstrap.c
    @@ -453,7 +453,7 @@ boot_openrel(char *relname)
     			Form_pg_attribute at = attrtypes[i];
     
     			elog(DEBUG4, "create attribute %d name %s len %d num %d type %u",
    -				 i, NameStr(at->attname), at->attlen, at->attnum,
    +				 i, NameStr(at->attname), at->attlen, at->attphysnum,
     				 at->atttypid);
     		}
     	}
    @@ -501,7 +501,7 @@ closerel(char *name)
      * ----------------
      */
     void
    -DefineAttr(char *name, char *type, int attnum, int nullness)
    +DefineAttr(char *name, char *type, int attphysnum, int nullness)
     {
     	Oid			typeoid;
     
    @@ -511,46 +511,46 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
     		closerel(NULL);
     	}
     
    -	if (attrtypes[attnum] == NULL)
    -		attrtypes[attnum] = AllocateAttribute();
    -	MemSet(attrtypes[attnum], 0, ATTRIBUTE_FIXED_PART_SIZE);
    +	if (attrtypes[attphysnum] == NULL)
    +		attrtypes[attphysnum] = AllocateAttribute();
    +	MemSet(attrtypes[attphysnum], 0, ATTRIBUTE_FIXED_PART_SIZE);
     
    -	namestrcpy(&attrtypes[attnum]->attname, name);
    -	elog(DEBUG4, "column %s %s", NameStr(attrtypes[attnum]->attname), type);
    -	attrtypes[attnum]->attnum = attnum + 1;
    +	namestrcpy(&attrtypes[attphysnum]->attname, name);
    +	elog(DEBUG4, "column %s %s", NameStr(attrtypes[attphysnum]->attname), type);
    +	attrtypes[attphysnum]->attphysnum = attphysnum + 1;
     
     	typeoid = gettype(type);
     
     	if (Typ != NIL)
     	{
    -		attrtypes[attnum]->atttypid = Ap->am_oid;
    -		attrtypes[attnum]->attlen = Ap->am_typ.typlen;
    -		attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;
    -		attrtypes[attnum]->attalign = Ap->am_typ.typalign;
    -		attrtypes[attnum]->attstorage = Ap->am_typ.typstorage;
    -		attrtypes[attnum]->attcompression = InvalidCompressionMethod;
    -		attrtypes[attnum]->attcollation = Ap->am_typ.typcollation;
    +		attrtypes[attphysnum]->atttypid = Ap->am_oid;
    +		attrtypes[attphysnum]->attlen = Ap->am_typ.typlen;
    +		attrtypes[attphysnum]->attbyval = Ap->am_typ.typbyval;
    +		attrtypes[attphysnum]->attalign = Ap->am_typ.typalign;
    +		attrtypes[attphysnum]->attstorage = Ap->am_typ.typstorage;
    +		attrtypes[attphysnum]->attcompression = InvalidCompressionMethod;
    +		attrtypes[attphysnum]->attcollation = Ap->am_typ.typcollation;
     		/* if an array type, assume 1-dimensional attribute */
     		if (Ap->am_typ.typelem != InvalidOid && Ap->am_typ.typlen < 0)
    -			attrtypes[attnum]->attndims = 1;
    +			attrtypes[attphysnum]->attndims = 1;
     		else
    -			attrtypes[attnum]->attndims = 0;
    +			attrtypes[attphysnum]->attndims = 0;
     	}
     	else
     	{
    -		attrtypes[attnum]->atttypid = TypInfo[typeoid].oid;
    -		attrtypes[attnum]->attlen = TypInfo[typeoid].len;
    -		attrtypes[attnum]->attbyval = TypInfo[typeoid].byval;
    -		attrtypes[attnum]->attalign = TypInfo[typeoid].align;
    -		attrtypes[attnum]->attstorage = TypInfo[typeoid].storage;
    -		attrtypes[attnum]->attcompression = InvalidCompressionMethod;
    -		attrtypes[attnum]->attcollation = TypInfo[typeoid].collation;
    +		attrtypes[attphysnum]->atttypid = TypInfo[typeoid].oid;
    +		attrtypes[attphysnum]->attlen = TypInfo[typeoid].len;
    +		attrtypes[attphysnum]->attbyval = TypInfo[typeoid].byval;
    +		attrtypes[attphysnum]->attalign = TypInfo[typeoid].align;
    +		attrtypes[attphysnum]->attstorage = TypInfo[typeoid].storage;
    +		attrtypes[attphysnum]->attcompression = InvalidCompressionMethod;
    +		attrtypes[attphysnum]->attcollation = TypInfo[typeoid].collation;
     		/* if an array type, assume 1-dimensional attribute */
     		if (TypInfo[typeoid].elem != InvalidOid &&
    -			attrtypes[attnum]->attlen < 0)
    -			attrtypes[attnum]->attndims = 1;
    +			attrtypes[attphysnum]->attlen < 0)
    +			attrtypes[attphysnum]->attndims = 1;
     		else
    -			attrtypes[attnum]->attndims = 0;
    +			attrtypes[attphysnum]->attndims = 0;
     	}
     
     	/*
    @@ -559,21 +559,21 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
     	 * collation.  This is essential to allow template0 to be cloned with a
     	 * different database collation.
     	 */
    -	if (OidIsValid(attrtypes[attnum]->attcollation))
    -		attrtypes[attnum]->attcollation = C_COLLATION_OID;
    +	if (OidIsValid(attrtypes[attphysnum]->attcollation))
    +		attrtypes[attphysnum]->attcollation = C_COLLATION_OID;
     
    -	attrtypes[attnum]->attstattarget = -1;
    -	attrtypes[attnum]->attcacheoff = -1;
    -	attrtypes[attnum]->atttypmod = -1;
    -	attrtypes[attnum]->attislocal = true;
    +	attrtypes[attphysnum]->attstattarget = -1;
    +	attrtypes[attphysnum]->attcacheoff = -1;
    +	attrtypes[attphysnum]->atttypmod = -1;
    +	attrtypes[attphysnum]->attislocal = true;
     
     	if (nullness == BOOTCOL_NULL_FORCE_NOT_NULL)
     	{
    -		attrtypes[attnum]->attnotnull = true;
    +		attrtypes[attphysnum]->attnotnull = true;
     	}
     	else if (nullness == BOOTCOL_NULL_FORCE_NULL)
     	{
    -		attrtypes[attnum]->attnotnull = false;
    +		attrtypes[attphysnum]->attnotnull = false;
     	}
     	else
     	{
    @@ -584,19 +584,19 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
     		 * likewise fixed-width and not-null.  This corresponds to case where
     		 * column can be accessed directly via C struct declaration.
     		 */
    -		if (attrtypes[attnum]->attlen > 0)
    +		if (attrtypes[attphysnum]->attlen > 0)
     		{
     			int			i;
     
     			/* check earlier attributes */
    -			for (i = 0; i < attnum; i++)
    +			for (i = 0; i < attphysnum; i++)
     			{
     				if (attrtypes[i]->attlen <= 0 ||
     					!attrtypes[i]->attnotnull)
     					break;
     			}
    -			if (i == attnum)
    -				attrtypes[attnum]->attnotnull = true;
    +			if (i == attphysnum)
    +				attrtypes[attphysnum]->attnotnull = true;
     		}
     	}
     }
    diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
    index 5f1726c095..3f5cbebcbc 100644
    --- a/src/backend/catalog/aclchk.c
    +++ b/src/backend/catalog/aclchk.c
    @@ -137,7 +137,7 @@ static AclMode restrict_and_check_grant(bool is_grant, AclMode avail_goptions,
     										Oid objectId, Oid grantorId,
     										ObjectType objtype, const char *objname,
     										AttrNumber att_number, const char *colname);
    -static AclMode pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum,
    +static AclMode pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attphysnum,
     						  Oid roleid, AclMode mask, AclMaskHow how);
     static void recordExtensionInitPriv(Oid objoid, Oid classoid, int objsubid,
     									Acl *new_acl);
    @@ -1578,18 +1578,18 @@ expand_col_privileges(List *colnames, Oid table_oid,
     	foreach(cell, colnames)
     	{
     		char	   *colname = strVal(lfirst(cell));
    -		AttrNumber	attnum;
    +		AttrNumber	attphysnum;
     
    -		attnum = get_attnum(table_oid, colname);
    -		if (attnum == InvalidAttrNumber)
    +		attphysnum = get_attphysnum(table_oid, colname);
    +		if (attphysnum == InvalidAttrNumber)
     			ereport(ERROR,
     					(errcode(ERRCODE_UNDEFINED_COLUMN),
     					 errmsg("column \"%s\" of relation \"%s\" does not exist",
     							colname, get_rel_name(table_oid))));
    -		attnum -= FirstLowInvalidHeapAttributeNumber;
    -		if (attnum <= 0 || attnum >= num_col_privileges)
    +		attphysnum -= FirstLowInvalidHeapAttributeNumber;
    +		if (attphysnum <= 0 || attphysnum >= num_col_privileges)
     			elog(ERROR, "column number out of range");	/* safety check */
    -		col_privileges[attnum] |= this_privileges;
    +		col_privileges[attphysnum] |= this_privileges;
     	}
     }
     
    @@ -1623,7 +1623,7 @@ expand_all_col_privileges(Oid table_oid, Form_pg_class classForm,
     		if (classForm->relkind == RELKIND_VIEW && curr_att < 0)
     			continue;
     
    -		attTuple = SearchSysCache2(ATTNUM,
    +		attTuple = SearchSysCache2(ATTPHYSNUM,
     								   ObjectIdGetDatum(table_oid),
     								   Int16GetDatum(curr_att));
     		if (!HeapTupleIsValid(attTuple))
    @@ -1648,7 +1648,7 @@ expand_all_col_privileges(Oid table_oid, Form_pg_class classForm,
      */
     static void
     ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
    -					AttrNumber attnum, Oid ownerId, AclMode col_privileges,
    +					AttrNumber attphysnum, Oid ownerId, AclMode col_privileges,
     					Relation attRelation, const Acl *old_rel_acl)
     {
     	HeapTuple	attr_tuple;
    @@ -1670,20 +1670,20 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
     	Oid		   *oldmembers;
     	Oid		   *newmembers;
     
    -	attr_tuple = SearchSysCache2(ATTNUM,
    +	attr_tuple = SearchSysCache2(ATTPHYSNUM,
     								 ObjectIdGetDatum(relOid),
    -								 Int16GetDatum(attnum));
    +								 Int16GetDatum(attphysnum));
     	if (!HeapTupleIsValid(attr_tuple))
     		elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -			 attnum, relOid);
    +			 attphysnum, relOid);
     	pg_attribute_tuple = (Form_pg_attribute) GETSTRUCT(attr_tuple);
     
     	/*
     	 * Get working copy of existing ACL. If there's no ACL, substitute the
     	 * proper default.
     	 */
    -	aclDatum = SysCacheGetAttr(ATTNUM, attr_tuple, Anum_pg_attribute_attacl,
    -							   &isNull);
    +	aclDatum = SysCacheGetAttr(ATTPHYSNUM, attr_tuple,
    +							   Anum_pg_attribute_attacl, &isNull);
     	if (isNull)
     	{
     		old_acl = acldefault(OBJECT_COLUMN, ownerId);
    @@ -1726,7 +1726,7 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
     								 (col_privileges == ACL_ALL_RIGHTS_COLUMN),
     								 col_privileges,
     								 relOid, grantorId, OBJECT_COLUMN,
    -								 relname, attnum,
    +								 relname, attphysnum,
     								 NameStr(pg_attribute_tuple->attname));
     
     	/*
    @@ -1776,11 +1776,11 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
     		CatalogTupleUpdate(attRelation, &newtuple->t_self, newtuple);
     
     		/* Update initial privileges for extensions */
    -		recordExtensionInitPriv(relOid, RelationRelationId, attnum,
    +		recordExtensionInitPriv(relOid, RelationRelationId, attphysnum,
     								ACL_NUM(new_acl) > 0 ? new_acl : NULL);
     
     		/* Update the shared dependency ACL info */
    -		updateAclDependencies(RelationRelationId, relOid, attnum,
    +		updateAclDependencies(RelationRelationId, relOid, attphysnum,
     							  ownerId,
     							  noldmembers, oldmembers,
     							  nnewmembers, newmembers);
    @@ -3840,7 +3840,7 @@ aclcheck_error_type(AclResult aclerr, Oid typeOid)
      * Relay for the various pg_*_mask routines depending on object kind
      */
     static AclMode
    -pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum, Oid roleid,
    +pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attphysnum, Oid roleid,
     		   AclMode mask, AclMaskHow how)
     {
     	switch (objtype)
    @@ -3848,7 +3848,7 @@ pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum, Oid roleid,
     		case OBJECT_COLUMN:
     			return
     				pg_class_aclmask(table_oid, roleid, mask, how) |
    -				pg_attribute_aclmask(table_oid, attnum, roleid, mask, how);
    +				pg_attribute_aclmask(table_oid, attphysnum, roleid, mask, how);
     		case OBJECT_TABLE:
     		case OBJECT_SEQUENCE:
     			return pg_class_aclmask(table_oid, roleid, mask, how);
    @@ -3910,10 +3910,10 @@ pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum, Oid roleid,
      * superuser-ness here.)
      */
     AclMode
    -pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
    +pg_attribute_aclmask(Oid table_oid, AttrNumber attphysnum, Oid roleid,
     					 AclMode mask, AclMaskHow how)
     {
    -	return pg_attribute_aclmask_ext(table_oid, attnum, roleid,
    +	return pg_attribute_aclmask_ext(table_oid, attphysnum, roleid,
     									mask, how, NULL);
     }
     
    @@ -3924,7 +3924,7 @@ pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid,
      * callers to avoid the missing attribute ERROR when is_missing is non-NULL.
      */
     AclMode
    -pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid,
    +pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attphysnum, Oid roleid,
     						 AclMode mask, AclMaskHow how, bool *is_missing)
     {
     	AclMode		result;
    @@ -3940,9 +3940,9 @@ pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid,
     	/*
     	 * First, get the column's ACL from its pg_attribute entry
     	 */
    -	attTuple = SearchSysCache2(ATTNUM,
    +	attTuple = SearchSysCache2(ATTPHYSNUM,
     							   ObjectIdGetDatum(table_oid),
    -							   Int16GetDatum(attnum));
    +							   Int16GetDatum(attphysnum));
     	if (!HeapTupleIsValid(attTuple))
     	{
     		if (is_missing != NULL)
    @@ -3955,7 +3955,7 @@ pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid,
     			ereport(ERROR,
     					(errcode(ERRCODE_UNDEFINED_COLUMN),
     					 errmsg("attribute %d of relation with OID %u does not exist",
    -							attnum, table_oid)));
    +							attphysnum, table_oid)));
     	}
     
     	attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple);
    @@ -3974,10 +3974,10 @@ pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid,
     			ereport(ERROR,
     					(errcode(ERRCODE_UNDEFINED_COLUMN),
     					 errmsg("attribute %d of relation with OID %u does not exist",
    -							attnum, table_oid)));
    +							attphysnum, table_oid)));
     	}
     
    -	aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
    +	aclDatum = SysCacheGetAttr(ATTPHYSNUM, attTuple, Anum_pg_attribute_attacl,
     							   &isNull);
     
     	/*
    @@ -4875,10 +4875,10 @@ pg_type_aclmask(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how)
      * column are considered here.
      */
     AclResult
    -pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
    +pg_attribute_aclcheck(Oid table_oid, AttrNumber attphysnum,
     					  Oid roleid, AclMode mode)
     {
    -	return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL);
    +	return pg_attribute_aclcheck_ext(table_oid, attphysnum, roleid, mode, NULL);
     }
     
     
    @@ -4889,10 +4889,10 @@ pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
      * callers to avoid the missing attribute ERROR when is_missing is non-NULL.
      */
     AclResult
    -pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum,
    +pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attphysnum,
     						  Oid roleid, AclMode mode, bool *is_missing)
     {
    -	if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode,
    +	if (pg_attribute_aclmask_ext(table_oid, attphysnum, roleid, mode,
     								 ACLMASK_ANY, is_missing) != 0)
     		return ACLCHECK_OK;
     	else
    @@ -4953,7 +4953,7 @@ pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode,
     		HeapTuple	attTuple;
     		AclMode		attmask;
     
    -		attTuple = SearchSysCache2(ATTNUM,
    +		attTuple = SearchSysCache2(ATTPHYSNUM,
     								   ObjectIdGetDatum(table_oid),
     								   Int16GetDatum(curr_att));
     		if (!HeapTupleIsValid(attTuple))
    @@ -6025,7 +6025,7 @@ recordExtObjInitPriv(Oid objoid, Oid classoid)
     				HeapTuple	attTuple;
     				Datum		attaclDatum;
     
    -				attTuple = SearchSysCache2(ATTNUM,
    +				attTuple = SearchSysCache2(ATTPHYSNUM,
     										   ObjectIdGetDatum(objoid),
     										   Int16GetDatum(curr_att));
     
    @@ -6039,7 +6039,7 @@ recordExtObjInitPriv(Oid objoid, Oid classoid)
     					continue;
     				}
     
    -				attaclDatum = SysCacheGetAttr(ATTNUM, attTuple,
    +				attaclDatum = SysCacheGetAttr(ATTPHYSNUM, attTuple,
     											  Anum_pg_attribute_attacl,
     											  &isNull);
     
    @@ -6318,7 +6318,7 @@ removeExtObjInitPriv(Oid objoid, Oid classoid)
     			{
     				HeapTuple	attTuple;
     
    -				attTuple = SearchSysCache2(ATTNUM,
    +				attTuple = SearchSysCache2(ATTPHYSNUM,
     										   ObjectIdGetDatum(objoid),
     										   Int16GetDatum(curr_att));
     
    diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c
    index e784538aae..44b4b03cac 100644
    --- a/src/backend/catalog/catalog.c
    +++ b/src/backend/catalog/catalog.c
    @@ -628,7 +628,7 @@ pg_nextoid(PG_FUNCTION_ARGS)
     						NameStr(*attname), RelationGetRelationName(rel))));
     
     	attform = ((Form_pg_attribute) GETSTRUCT(atttuple));
    -	attno = attform->attnum;
    +	attno = attform->attphysnum;
     
     	if (attform->atttypid != OIDOID)
     		ereport(ERROR,
    diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
    index 17b2c5e3f3..f1d33dd949 100644
    --- a/src/backend/catalog/genbki.pl
    +++ b/src/backend/catalog/genbki.pl
    @@ -508,10 +508,10 @@ EOM
     	print $bki "\n (\n";
     	my $schema = $catalog->{columns};
     	my %attnames;
    -	my $attnum = 0;
    +	my $attphysnum = 0;
     	foreach my $column (@$schema)
     	{
    -		$attnum++;
    +		$attphysnum++;
     		my $attname = $column->{name};
     		my $atttype = $column->{type};
     
    @@ -537,12 +537,12 @@ EOM
     		}
     
     		# Emit Anum_* constants
    -		printf $def "#define Anum_%s_%s %s\n", $catname, $attname, $attnum;
    +		printf $def "#define Anum_%s_%s %s\n", $catname, $attname, $attphysnum;
     	}
     	print $bki "\n )\n";
     
     	# Emit Natts_* constant
    -	print $def "\n#define Natts_$catname $attnum\n\n";
    +	print $def "\n#define Natts_$catname $attphysnum\n\n";
     
     	# Emit client code copied from source header
     	foreach my $line (@{ $catalog->{client_code} })
    @@ -845,13 +845,13 @@ sub gen_pg_attribute
     		push @tables_needing_macros, $table_name;
     
     		# Generate entries for user attributes.
    -		my $attnum          = 0;
    +		my $attphysnum          = 0;
     		my $priorfixedwidth = 1;
     		foreach my $attr (@{ $table->{columns} })
     		{
    -			$attnum++;
    +			$attphysnum++;
     			my %row;
    -			$row{attnum}   = $attnum;
    +			$row{attphysnum}   = $attphysnum;
     			$row{attrelid} = $table->{relation_oid};
     
     			morph_row_for_pgattr(\%row, $schema, $attr, $priorfixedwidth);
    @@ -875,7 +875,7 @@ sub gen_pg_attribute
     		# We only need postgres.bki entries, not schemapg.h entries.
     		if ($table->{bootstrap})
     		{
    -			$attnum = 0;
    +			$attphysnum = 0;
     			my @SYS_ATTRS = (
     				{ name => 'ctid',     type => 'tid' },
     				{ name => 'xmin',     type => 'xid' },
    @@ -885,9 +885,9 @@ sub gen_pg_attribute
     				{ name => 'tableoid', type => 'oid' });
     			foreach my $attr (@SYS_ATTRS)
     			{
    -				$attnum--;
    +				$attphysnum--;
     				my %row;
    -				$row{attnum}        = $attnum;
    +				$row{attphysnum}        = $attphysnum;
     				$row{attrelid}      = $table->{relation_oid};
     				$row{attstattarget} = '0';
     
    diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
    index 1803194db9..ed9929e67a 100644
    --- a/src/backend/catalog/heap.c
    +++ b/src/backend/catalog/heap.c
    @@ -142,7 +142,7 @@ static const FormData_pg_attribute a1 = {
     	.attname = {"ctid"},
     	.atttypid = TIDOID,
     	.attlen = sizeof(ItemPointerData),
    -	.attnum = SelfItemPointerAttributeNumber,
    +	.attphysnum = SelfItemPointerAttributeNumber,
     	.attcacheoff = -1,
     	.atttypmod = -1,
     	.attbyval = false,
    @@ -156,7 +156,7 @@ static const FormData_pg_attribute a2 = {
     	.attname = {"xmin"},
     	.atttypid = XIDOID,
     	.attlen = sizeof(TransactionId),
    -	.attnum = MinTransactionIdAttributeNumber,
    +	.attphysnum = MinTransactionIdAttributeNumber,
     	.attcacheoff = -1,
     	.atttypmod = -1,
     	.attbyval = true,
    @@ -170,7 +170,7 @@ static const FormData_pg_attribute a3 = {
     	.attname = {"cmin"},
     	.atttypid = CIDOID,
     	.attlen = sizeof(CommandId),
    -	.attnum = MinCommandIdAttributeNumber,
    +	.attphysnum = MinCommandIdAttributeNumber,
     	.attcacheoff = -1,
     	.atttypmod = -1,
     	.attbyval = true,
    @@ -184,7 +184,7 @@ static const FormData_pg_attribute a4 = {
     	.attname = {"xmax"},
     	.atttypid = XIDOID,
     	.attlen = sizeof(TransactionId),
    -	.attnum = MaxTransactionIdAttributeNumber,
    +	.attphysnum = MaxTransactionIdAttributeNumber,
     	.attcacheoff = -1,
     	.atttypmod = -1,
     	.attbyval = true,
    @@ -198,7 +198,7 @@ static const FormData_pg_attribute a5 = {
     	.attname = {"cmax"},
     	.atttypid = CIDOID,
     	.attlen = sizeof(CommandId),
    -	.attnum = MaxCommandIdAttributeNumber,
    +	.attphysnum = MaxCommandIdAttributeNumber,
     	.attcacheoff = -1,
     	.atttypmod = -1,
     	.attbyval = true,
    @@ -218,7 +218,7 @@ static const FormData_pg_attribute a6 = {
     	.attname = {"tableoid"},
     	.atttypid = OIDOID,
     	.attlen = sizeof(Oid),
    -	.attnum = TableOidAttributeNumber,
    +	.attphysnum = TableOidAttributeNumber,
     	.attcacheoff = -1,
     	.atttypmod = -1,
     	.attbyval = true,
    @@ -731,7 +731,7 @@ InsertPgAttributeTuples(Relation pg_attribute_rel,
     		slot[slotCount]->tts_values[Anum_pg_attribute_atttypid - 1] = ObjectIdGetDatum(attrs->atttypid);
     		slot[slotCount]->tts_values[Anum_pg_attribute_attstattarget - 1] = Int32GetDatum(attrs->attstattarget);
     		slot[slotCount]->tts_values[Anum_pg_attribute_attlen - 1] = Int16GetDatum(attrs->attlen);
    -		slot[slotCount]->tts_values[Anum_pg_attribute_attnum - 1] = Int16GetDatum(attrs->attnum);
    +		slot[slotCount]->tts_values[Anum_pg_attribute_attphysnum - 1] = Int16GetDatum(attrs->attphysnum);
     		slot[slotCount]->tts_values[Anum_pg_attribute_attndims - 1] = Int32GetDatum(attrs->attndims);
     		slot[slotCount]->tts_values[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(-1);
     		slot[slotCount]->tts_values[Anum_pg_attribute_atttypmod - 1] = Int32GetDatum(attrs->atttypmod);
    @@ -1578,7 +1578,7 @@ DeleteAttributeTuples(Oid relid)
     				BTEqualStrategyNumber, F_OIDEQ,
     				ObjectIdGetDatum(relid));
     
    -	scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true,
    +	scan = systable_beginscan(attrel, AttributeRelidPhysNumIndexId, true,
     							  NULL, 1, key);
     
     	/* Delete all the matching tuples */
    @@ -1615,11 +1615,11 @@ DeleteSystemAttributeTuples(Oid relid)
     				BTEqualStrategyNumber, F_OIDEQ,
     				ObjectIdGetDatum(relid));
     	ScanKeyInit(&key[1],
    -				Anum_pg_attribute_attnum,
    +				Anum_pg_attribute_attphysnum,
     				BTLessEqualStrategyNumber, F_INT2LE,
     				Int16GetDatum(0));
     
    -	scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true,
    +	scan = systable_beginscan(attrel, AttributeRelidPhysNumIndexId, true,
     							  NULL, 2, key);
     
     	/* Delete all the matching tuples */
    @@ -1640,7 +1640,7 @@ DeleteSystemAttributeTuples(Oid relid)
      * is handled by dependency.c.)
      */
     void
    -RemoveAttributeById(Oid relid, AttrNumber attnum)
    +RemoveAttributeById(Oid relid, AttrNumber attphysnum)
     {
     	Relation	rel;
     	Relation	attr_rel;
    @@ -1658,15 +1658,15 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
     
     	attr_rel = table_open(AttributeRelationId, RowExclusiveLock);
     
    -	tuple = SearchSysCacheCopy2(ATTNUM,
    +	tuple = SearchSysCacheCopy2(ATTPHYSNUM,
     								ObjectIdGetDatum(relid),
    -								Int16GetDatum(attnum));
    +								Int16GetDatum(attphysnum));
     	if (!HeapTupleIsValid(tuple))	/* shouldn't happen */
     		elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -			 attnum, relid);
    +			 attphysnum, relid);
     	attStruct = (Form_pg_attribute) GETSTRUCT(tuple);
     
    -	if (attnum < 0)
    +	if (attphysnum < 0)
     	{
     		/* System attribute (probably OID) ... just delete the row */
     
    @@ -1703,7 +1703,7 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
     		 * Change the column name to something that isn't likely to conflict
     		 */
     		snprintf(newattname, sizeof(newattname),
    -				 "........pg.dropped.%d........", attnum);
    +				 "........pg.dropped.%d........", attphysnum);
     		namestrcpy(&(attStruct->attname), newattname);
     
     		/* clear the missing value if any */
    @@ -1740,8 +1740,8 @@ RemoveAttributeById(Oid relid, AttrNumber attnum)
     
     	table_close(attr_rel, RowExclusiveLock);
     
    -	if (attnum > 0)
    -		RemoveStatistics(relid, attnum);
    +	if (attphysnum > 0)
    +		RemoveStatistics(relid, attphysnum);
     
     	relation_close(rel, NoLock);
     }
    @@ -1941,7 +1941,7 @@ RelationClearMissing(Relation rel)
     	Relation	attr_rel;
     	Oid			relid = RelationGetRelid(rel);
     	int			natts = RelationGetNumberOfAttributes(rel);
    -	int			attnum;
    +	int			attphysnum;
     	Datum		repl_val[Natts_pg_attribute];
     	bool		repl_null[Natts_pg_attribute];
     	bool		repl_repl[Natts_pg_attribute];
    @@ -1964,14 +1964,14 @@ RelationClearMissing(Relation rel)
     	attr_rel = table_open(AttributeRelationId, RowExclusiveLock);
     
     	/* process each non-system attribute, including any dropped columns */
    -	for (attnum = 1; attnum <= natts; attnum++)
    +	for (attphysnum = 1; attphysnum <= natts; attphysnum++)
     	{
    -		tuple = SearchSysCache2(ATTNUM,
    +		tuple = SearchSysCache2(ATTPHYSNUM,
     								ObjectIdGetDatum(relid),
    -								Int16GetDatum(attnum));
    +								Int16GetDatum(attphysnum));
     		if (!HeapTupleIsValid(tuple))	/* shouldn't happen */
     			elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -				 attnum, relid);
    +				 attphysnum, relid);
     
     		attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
     
    @@ -2201,7 +2201,7 @@ StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal)
     		switch (con->contype)
     		{
     			case CONSTR_DEFAULT:
    -				con->conoid = StoreAttrDefault(rel, con->attnum, con->expr,
    +				con->conoid = StoreAttrDefault(rel, con->attphysnum, con->expr,
     											   is_internal, false);
     				break;
     			case CONSTR_CHECK:
    @@ -2301,7 +2301,7 @@ AddRelationNewConstraints(Relation rel,
     	foreach(cell, newColDefaults)
     	{
     		RawColumnDefault *colDef = (RawColumnDefault *) lfirst(cell);
    -		Form_pg_attribute atp = TupleDescAttr(rel->rd_att, colDef->attnum - 1);
    +		Form_pg_attribute atp = TupleDescAttr(rel->rd_att, colDef->attphysnum - 1);
     		Oid			defOid;
     
     		expr = cookDefault(pstate, colDef->raw_default,
    @@ -2331,14 +2331,14 @@ AddRelationNewConstraints(Relation rel,
     		if (colDef->missingMode && contain_volatile_functions((Node *) expr))
     			colDef->missingMode = false;
     
    -		defOid = StoreAttrDefault(rel, colDef->attnum, expr, is_internal,
    +		defOid = StoreAttrDefault(rel, colDef->attphysnum, expr, is_internal,
     								  colDef->missingMode);
     
     		cooked = (CookedConstraint *) palloc(sizeof(CookedConstraint));
     		cooked->contype = CONSTR_DEFAULT;
     		cooked->conoid = defOid;
     		cooked->name = NULL;
    -		cooked->attnum = colDef->attnum;
    +		cooked->attphysnum = colDef->attphysnum;
     		cooked->expr = expr;
     		cooked->skip_validation = false;
     		cooked->is_local = is_local;
    @@ -2469,7 +2469,7 @@ AddRelationNewConstraints(Relation rel,
     		cooked->contype = CONSTR_CHECK;
     		cooked->conoid = constrOid;
     		cooked->name = ccname;
    -		cooked->attnum = 0;
    +		cooked->attphysnum = 0;
     		cooked->expr = expr;
     		cooked->skip_validation = cdef->skip_validation;
     		cooked->is_local = is_local;
    @@ -2695,23 +2695,23 @@ check_nested_generated_walker(Node *node, void *context)
     	{
     		Var		   *var = (Var *) node;
     		Oid			relid;
    -		AttrNumber	attnum;
    +		AttrNumber	attphysnum;
     
     		relid = rt_fetch(var->varno, pstate->p_rtable)->relid;
     		if (!OidIsValid(relid))
     			return false;		/* XXX shouldn't we raise an error? */
     
    -		attnum = var->varattno;
    +		attphysnum = var->varattno;
     
    -		if (attnum > 0 && get_attgenerated(relid, attnum))
    +		if (attphysnum > 0 && get_attgenerated(relid, attphysnum))
     			ereport(ERROR,
     					(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
     					 errmsg("cannot use generated column \"%s\" in column generation expression",
    -							get_attname(relid, attnum, false)),
    +							get_attname(relid, attphysnum, false)),
     					 errdetail("A generated column cannot reference another generated column."),
     					 parser_errposition(pstate, var->location)));
     		/* A whole-row Var is necessarily self-referential, so forbid it */
    -		if (attnum == 0)
    +		if (attphysnum == 0)
     			ereport(ERROR,
     					(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
     					 errmsg("cannot use whole-row variable in column generation expression"),
    @@ -2899,11 +2899,11 @@ CopyStatistics(Oid fromrelid, Oid torelid)
     /*
      * RemoveStatistics --- remove entries in pg_statistic for a rel or column
      *
    - * If attnum is zero, remove all entries for rel; else remove only the one(s)
    + * If attphysnum is zero, remove all entries for rel; else remove only the one(s)
      * for that column.
      */
     void
    -RemoveStatistics(Oid relid, AttrNumber attnum)
    +RemoveStatistics(Oid relid, AttrNumber attphysnum)
     {
     	Relation	pgstatistic;
     	SysScanDesc scan;
    @@ -2918,21 +2918,21 @@ RemoveStatistics(Oid relid, AttrNumber attnum)
     				BTEqualStrategyNumber, F_OIDEQ,
     				ObjectIdGetDatum(relid));
     
    -	if (attnum == 0)
    +	if (attphysnum == 0)
     		nkeys = 1;
     	else
     	{
     		ScanKeyInit(&key[1],
     					Anum_pg_statistic_staattnum,
     					BTEqualStrategyNumber, F_INT2EQ,
    -					Int16GetDatum(attnum));
    +					Int16GetDatum(attphysnum));
     		nkeys = 2;
     	}
     
     	scan = systable_beginscan(pgstatistic, StatisticRelidAttnumInhIndexId, true,
     							  NULL, nkeys, key);
     
    -	/* we must loop even when attnum != 0, in case of inherited stats */
    +	/* we must loop even when attphysnum != 0, in case of inherited stats */
     	while (HeapTupleIsValid(tuple = systable_getnext(scan)))
     		CatalogTupleDelete(pgstatistic, &tuple->t_self);
     
    diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
    index bdd3c34841..c514e3b622 100644
    --- a/src/backend/catalog/index.c
    +++ b/src/backend/catalog/index.c
    @@ -231,25 +231,25 @@ index_check_primary_key(Relation heapRel,
     	 */
     	for (i = 0; i < indexInfo->ii_NumIndexKeyAttrs; i++)
     	{
    -		AttrNumber	attnum = indexInfo->ii_IndexAttrNumbers[i];
    +		AttrNumber	attphysnum = indexInfo->ii_IndexAttrNumbers[i];
     		HeapTuple	atttuple;
     		Form_pg_attribute attform;
     
    -		if (attnum == 0)
    +		if (attphysnum == 0)
     			ereport(ERROR,
     					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     					 errmsg("primary keys cannot be expressions")));
     
     		/* System attributes are never null, so no need to check */
    -		if (attnum < 0)
    +		if (attphysnum < 0)
     			continue;
     
    -		atttuple = SearchSysCache2(ATTNUM,
    +		atttuple = SearchSysCache2(ATTPHYSNUM,
     								   ObjectIdGetDatum(RelationGetRelid(heapRel)),
    -								   Int16GetDatum(attnum));
    +								   Int16GetDatum(attphysnum));
     		if (!HeapTupleIsValid(atttuple))
     			elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -				 attnum, RelationGetRelid(heapRel));
    +				 attphysnum, RelationGetRelid(heapRel));
     		attform = (Form_pg_attribute) GETSTRUCT(atttuple);
     
     		if (!attform->attnotnull)
    @@ -310,7 +310,7 @@ ConstructTupleDescriptor(Relation heapRelation,
     		Oid			keyType;
     
     		MemSet(to, 0, ATTRIBUTE_FIXED_PART_SIZE);
    -		to->attnum = i + 1;
    +		to->attphysnum = i + 1;
     		to->attstattarget = -1;
     		to->attcacheoff = -1;
     		to->attislocal = true;
    @@ -1770,7 +1770,7 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
     					Anum_pg_attribute_attrelid,
     					BTEqualStrategyNumber, F_OIDEQ,
     					ObjectIdGetDatum(newIndexId));
    -		scan = systable_beginscan(pg_attribute, AttributeRelidNumIndexId,
    +		scan = systable_beginscan(pg_attribute, AttributeRelidPhysNumIndexId,
     								  true, NULL, 1, key);
     
     		while (HeapTupleIsValid((attrTuple = systable_getnext(scan))))
    @@ -1789,7 +1789,7 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
     			/*
     			 * Get attstattarget from the old index and refresh the new value.
     			 */
    -			attstattarget = get_attstattarget(oldIndexId, att->attnum);
    +			attstattarget = get_attstattarget(oldIndexId, att->attphysnum);
     
     			/* no need for a refresh if both match */
     			if (attstattarget == att->attstattarget)
    diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c
    index 0b92093322..6c5052c0de 100644
    --- a/src/backend/catalog/indexing.c
    +++ b/src/backend/catalog/indexing.c
    @@ -191,11 +191,11 @@ CatalogTupleCheckConstraints(Relation heapRel, HeapTuple tup)
     		TupleDesc	tupdesc = RelationGetDescr(heapRel);
     		bits8	   *bp = tup->t_data->t_bits;
     
    -		for (int attnum = 0; attnum < tupdesc->natts; attnum++)
    +		for (int attphysnum = 0; attphysnum < tupdesc->natts; attphysnum++)
     		{
    -			Form_pg_attribute thisatt = TupleDescAttr(tupdesc, attnum);
    +			Form_pg_attribute thisatt = TupleDescAttr(tupdesc, attphysnum);
     
    -			Assert(!(thisatt->attnotnull && att_isnull(attnum, bp)));
    +			Assert(!(thisatt->attnotnull && att_isnull(attphysnum, bp)));
     		}
     	}
     }
    diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
    index 18725a02d1..90004ea3bc 100644
    --- a/src/backend/catalog/information_schema.sql
    +++ b/src/backend/catalog/information_schema.sql
    @@ -293,7 +293,7 @@ CREATE VIEW attributes AS
                CAST(nc.nspname AS sql_identifier) AS udt_schema,
                CAST(c.relname AS sql_identifier) AS udt_name,
                CAST(a.attname AS sql_identifier) AS attribute_name,
    -           CAST(a.attnum AS cardinal_number) AS ordinal_position,
    +           CAST(a.attphysnum AS cardinal_number) AS ordinal_position,
                CAST(pg_get_expr(ad.adbin, ad.adrelid) AS character_data) AS attribute_default,
                CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END
                  AS yes_or_no)
    @@ -359,16 +359,16 @@ CREATE VIEW attributes AS
                CAST(null AS sql_identifier) AS scope_name,
     
                CAST(null AS cardinal_number) AS maximum_cardinality,
    -           CAST(a.attnum AS sql_identifier) AS dtd_identifier,
    +           CAST(a.attphysnum AS sql_identifier) AS dtd_identifier,
                CAST('NO' AS yes_or_no) AS is_derived_reference_attribute
     
    -    FROM (pg_attribute a LEFT JOIN pg_attrdef ad ON attrelid = adrelid AND attnum = adnum)
    +    FROM (pg_attribute a LEFT JOIN pg_attrdef ad ON attrelid = adrelid AND attphysnum = adnum)
              JOIN (pg_class c JOIN pg_namespace nc ON (c.relnamespace = nc.oid)) ON a.attrelid = c.oid
              JOIN (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) ON a.atttypid = t.oid
              LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid))
                ON a.attcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default')
     
    -    WHERE a.attnum > 0 AND NOT a.attisdropped
    +    WHERE a.attphysnum > 0 AND NOT a.attisdropped
               AND c.relkind IN ('c')
               AND (pg_has_role(c.relowner, 'USAGE')
                    OR has_type_privilege(c.reltype, 'USAGE'));
    @@ -449,13 +449,13 @@ CREATE VIEW check_constraints AS
     
         SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
                CAST(n.nspname AS sql_identifier) AS constraint_schema,
    -           CAST(CAST(n.oid AS text) || '_' || CAST(r.oid AS text) || '_' || CAST(a.attnum AS text) || '_not_null' AS sql_identifier) AS constraint_name, -- XXX
    +           CAST(CAST(n.oid AS text) || '_' || CAST(r.oid AS text) || '_' || CAST(a.attphysnum AS text) || '_not_null' AS sql_identifier) AS constraint_name, -- XXX
                CAST(a.attname || ' IS NOT NULL' AS character_data)
                  AS check_clause
         FROM pg_namespace n, pg_class r, pg_attribute a
         WHERE n.oid = r.relnamespace
           AND r.oid = a.attrelid
    -      AND a.attnum > 0
    +      AND a.attphysnum > 0
           AND NOT a.attisdropped
           AND a.attnotnull
           AND r.relkind IN ('r', 'p')
    @@ -519,14 +519,14 @@ CREATE VIEW column_column_usage AS
         WHERE n.oid = c.relnamespace
               AND c.oid = ac.attrelid
               AND c.oid = ad.attrelid
    -          AND ac.attnum <> ad.attnum
    +          AND ac.attphysnum <> ad.attphysnum
               AND ad.attrelid = atd.adrelid
    -          AND ad.attnum = atd.adnum
    +          AND ad.attphysnum = atd.adnum
               AND d.classid = 'pg_catalog.pg_attrdef'::regclass
               AND d.refclassid = 'pg_catalog.pg_class'::regclass
               AND d.objid = atd.oid
               AND d.refobjid = ac.attrelid
    -          AND d.refobjsubid = ac.attnum
    +          AND d.refobjsubid = ac.attphysnum
               AND ad.attgenerated <> ''
               AND pg_has_role(c.relowner, 'USAGE');
     
    @@ -556,7 +556,7 @@ CREATE VIEW column_domain_usage AS
               AND a.atttypid = t.oid
               AND t.typtype = 'd'
               AND c.relkind IN ('r', 'v', 'f', 'p')
    -          AND a.attnum > 0
    +          AND a.attphysnum > 0
               AND NOT a.attisdropped
               AND pg_has_role(t.typowner, 'USAGE');
     
    @@ -598,7 +598,7 @@ CREATE VIEW column_privileges AS
                     ) pr_c (oid, relname, relnamespace, relowner, grantor, grantee, prtype, grantable),
                     pg_attribute a
                WHERE a.attrelid = pr_c.oid
    -                 AND a.attnum > 0
    +                 AND a.attphysnum > 0
                      AND NOT a.attisdropped
                UNION
                SELECT pr_a.grantor,
    @@ -611,7 +611,7 @@ CREATE VIEW column_privileges AS
                       c.relowner
                FROM (SELECT attrelid, attname, (aclexplode(coalesce(attacl, acldefault('c', relowner)))).*
                      FROM pg_attribute a JOIN pg_class cc ON (a.attrelid = cc.oid)
    -                 WHERE attnum > 0
    +                 WHERE attphysnum > 0
                            AND NOT attisdropped
                     ) pr_a (attrelid, attname, grantor, grantee, prtype, grantable),
                     pg_class c
    @@ -659,7 +659,7 @@ CREATE VIEW column_udt_usage AS
         WHERE a.attrelid = c.oid
               AND a.atttypid = t.oid
               AND nc.oid = c.relnamespace
    -          AND a.attnum > 0 AND NOT a.attisdropped
    +          AND a.attphysnum > 0 AND NOT a.attisdropped
               AND c.relkind in ('r', 'v', 'f', 'p')
               AND pg_has_role(coalesce(bt.typowner, t.typowner), 'USAGE');
     
    @@ -676,7 +676,7 @@ CREATE VIEW columns AS
                CAST(nc.nspname AS sql_identifier) AS table_schema,
                CAST(c.relname AS sql_identifier) AS table_name,
                CAST(a.attname AS sql_identifier) AS column_name,
    -           CAST(a.attnum AS cardinal_number) AS ordinal_position,
    +           CAST(a.attphysnum AS cardinal_number) AS ordinal_position,
                CAST(CASE WHEN a.attgenerated = '' THEN pg_get_expr(ad.adbin, ad.adrelid) END AS character_data) AS column_default,
                CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END
                  AS yes_or_no)
    @@ -755,7 +755,7 @@ CREATE VIEW columns AS
                CAST(null AS sql_identifier) AS scope_name,
     
                CAST(null AS cardinal_number) AS maximum_cardinality,
    -           CAST(a.attnum AS sql_identifier) AS dtd_identifier,
    +           CAST(a.attphysnum AS sql_identifier) AS dtd_identifier,
                CAST('NO' AS yes_or_no) AS is_self_referencing,
     
                CAST(CASE WHEN a.attidentity IN ('a', 'd') THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_identity,
    @@ -771,10 +771,10 @@ CREATE VIEW columns AS
     
                CAST(CASE WHEN c.relkind IN ('r', 'p') OR
                               (c.relkind IN ('v', 'f') AND
    -                           pg_column_is_updatable(c.oid, a.attnum, false))
    +                           pg_column_is_updatable(c.oid, a.attphysnum, false))
                     THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_updatable
     
    -    FROM (pg_attribute a LEFT JOIN pg_attrdef ad ON attrelid = adrelid AND attnum = adnum)
    +    FROM (pg_attribute a LEFT JOIN pg_attrdef ad ON attrelid = adrelid AND attphysnum = adnum)
              JOIN (pg_class c JOIN pg_namespace nc ON (c.relnamespace = nc.oid)) ON a.attrelid = c.oid
              JOIN (pg_type t JOIN pg_namespace nt ON (t.typnamespace = nt.oid)) ON a.atttypid = t.oid
              LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON (bt.typnamespace = nbt.oid))
    @@ -782,15 +782,15 @@ CREATE VIEW columns AS
              LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid))
                ON a.attcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default')
              LEFT JOIN (pg_depend dep JOIN pg_sequence seq ON (dep.classid = 'pg_class'::regclass AND dep.objid = seq.seqrelid AND dep.deptype = 'i'))
    -           ON (dep.refclassid = 'pg_class'::regclass AND dep.refobjid = c.oid AND dep.refobjsubid = a.attnum)
    +           ON (dep.refclassid = 'pg_class'::regclass AND dep.refobjid = c.oid AND dep.refobjsubid = a.attphysnum)
     
         WHERE (NOT pg_is_other_temp_schema(nc.oid))
     
    -          AND a.attnum > 0 AND NOT a.attisdropped
    +          AND a.attphysnum > 0 AND NOT a.attisdropped
               AND c.relkind IN ('r', 'v', 'f', 'p')
     
               AND (pg_has_role(c.relowner, 'USAGE')
    -               OR has_column_privilege(c.oid, a.attnum,
    +               OR has_column_privilege(c.oid, a.attphysnum,
                                            'SELECT, INSERT, UPDATE, REFERENCES'));
     
     GRANT SELECT ON columns TO PUBLIC;
    @@ -818,7 +818,7 @@ CREATE VIEW constraint_column_usage AS
                 AND r.oid = a.attrelid
                 AND d.refclassid = 'pg_catalog.pg_class'::regclass
                 AND d.refobjid = r.oid
    -            AND d.refobjsubid = a.attnum
    +            AND d.refobjsubid = a.attphysnum
                 AND d.classid = 'pg_catalog.pg_constraint'::regclass
                 AND d.objid = c.oid
                 AND c.connamespace = nc.oid
    @@ -836,7 +836,7 @@ CREATE VIEW constraint_column_usage AS
                 AND r.oid = a.attrelid
                 AND nc.oid = c.connamespace
                 AND r.oid = CASE c.contype WHEN 'f' THEN c.confrelid ELSE c.conrelid END
    -            AND a.attnum = ANY (CASE c.contype WHEN 'f' THEN c.confkey ELSE c.conkey END)
    +            AND a.attphysnum = ANY (CASE c.contype WHEN 'f' THEN c.confkey ELSE c.conkey END)
                 AND NOT a.attisdropped
                 AND c.contype IN ('p', 'u', 'f')
                 AND r.relkind IN ('r', 'p')
    @@ -1095,10 +1095,10 @@ CREATE VIEW key_column_usage AS
                     AND r.relkind IN ('r', 'p')
                     AND (NOT pg_is_other_temp_schema(nr.oid)) ) AS ss
         WHERE ss.roid = a.attrelid
    -          AND a.attnum = (ss.x).x
    +          AND a.attphysnum = (ss.x).x
               AND NOT a.attisdropped
               AND (pg_has_role(relowner, 'USAGE')
    -               OR has_column_privilege(roid, a.attnum,
    +               OR has_column_privilege(roid, a.attphysnum,
                                            'SELECT, INSERT, UPDATE, REFERENCES'));
     
     GRANT SELECT ON key_column_usage TO PUBLIC;
    @@ -1352,7 +1352,7 @@ CREATE VIEW routine_column_usage AS
               AND t.relnamespace = nt.oid
               AND t.relkind IN ('r', 'v', 'f', 'p')
               AND t.oid = a.attrelid
    -          AND d.refobjsubid = a.attnum
    +          AND d.refobjsubid = a.attphysnum
               AND pg_has_role(t.relowner, 'USAGE');
     
     GRANT SELECT ON routine_column_usage TO PUBLIC;
    @@ -1867,7 +1867,7 @@ CREATE VIEW table_constraints AS
     
         SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog,
                CAST(nr.nspname AS sql_identifier) AS constraint_schema,
    -           CAST(CAST(nr.oid AS text) || '_' || CAST(r.oid AS text) || '_' || CAST(a.attnum AS text) || '_not_null' AS sql_identifier) AS constraint_name, -- XXX
    +           CAST(CAST(nr.oid AS text) || '_' || CAST(r.oid AS text) || '_' || CAST(a.attphysnum AS text) || '_not_null' AS sql_identifier) AS constraint_name, -- XXX
                CAST(current_database() AS sql_identifier) AS table_catalog,
                CAST(nr.nspname AS sql_identifier) AS table_schema,
                CAST(r.relname AS sql_identifier) AS table_name,
    @@ -1884,7 +1884,7 @@ CREATE VIEW table_constraints AS
         WHERE nr.oid = r.relnamespace
               AND r.oid = a.attrelid
               AND a.attnotnull
    -          AND a.attnum > 0
    +          AND a.attphysnum > 0
               AND NOT a.attisdropped
               AND r.relkind IN ('r', 'p')
               AND (NOT pg_is_other_temp_schema(nr.oid))
    @@ -2084,12 +2084,12 @@ CREATE VIEW triggered_update_columns AS
         WHERE n.oid = c.relnamespace
               AND c.oid = t.tgrelid
               AND t.oid = ta.tgoid
    -          AND (a.attrelid, a.attnum) = (t.tgrelid, ta.tgattnum)
    +          AND (a.attrelid, a.attphysnum) = (t.tgrelid, ta.tgattnum)
               AND NOT t.tgisinternal
               AND (NOT pg_is_other_temp_schema(n.oid))
               AND (pg_has_role(c.relowner, 'USAGE')
                    -- SELECT privilege omitted, per SQL standard
    -               OR has_column_privilege(c.oid, a.attnum, 'INSERT, UPDATE, REFERENCES') );
    +               OR has_column_privilege(c.oid, a.attphysnum, 'INSERT, UPDATE, REFERENCES') );
     
     GRANT SELECT ON triggered_update_columns TO PUBLIC;
     
    @@ -2537,7 +2537,7 @@ CREATE VIEW view_column_usage AS
               AND t.relnamespace = nt.oid
               AND t.relkind IN ('r', 'v', 'f', 'p')
               AND t.oid = a.attrelid
    -          AND dt.refobjsubid = a.attnum
    +          AND dt.refobjsubid = a.attphysnum
               AND pg_has_role(t.relowner, 'USAGE');
     
     GRANT SELECT ON view_column_usage TO PUBLIC;
    @@ -2763,11 +2763,11 @@ CREATE VIEW element_types AS
                /* columns, attributes */
                SELECT c.relnamespace, CAST(c.relname AS sql_identifier),
                       CASE WHEN c.relkind = 'c' THEN 'USER-DEFINED TYPE'::text ELSE 'TABLE'::text END,
    -                  a.attnum, a.atttypid, a.attcollation
    +                  a.attphysnum, a.atttypid, a.attcollation
                FROM pg_class c, pg_attribute a
                WHERE c.oid = a.attrelid
                      AND c.relkind IN ('r', 'v', 'f', 'c', 'p')
    -                 AND attnum > 0 AND NOT attisdropped
    +                 AND attphysnum > 0 AND NOT attisdropped
     
                UNION ALL
     
    @@ -2824,12 +2824,12 @@ CREATE VIEW _pg_foreign_table_columns AS
              pg_attribute a
         WHERE u.oid = c.relowner
               AND (pg_has_role(c.relowner, 'USAGE')
    -               OR has_column_privilege(c.oid, a.attnum, 'SELECT, INSERT, UPDATE, REFERENCES'))
    +               OR has_column_privilege(c.oid, a.attphysnum, 'SELECT, INSERT, UPDATE, REFERENCES'))
               AND n.oid = c.relnamespace
               AND c.oid = t.ftrelid
               AND c.relkind = 'f'
               AND a.attrelid = c.oid
    -          AND a.attnum > 0;
    +          AND a.attphysnum > 0;
     
     /*
      * 24.2
    diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
    index 8377b4f7d4..e373637651 100644
    --- a/src/backend/catalog/objectaddress.c
    +++ b/src/backend/catalog/objectaddress.c
    @@ -107,10 +107,10 @@ typedef struct
     									 * (name) if the object does not live in a
     									 * namespace */
     	AttrNumber	attnum_oid;		/* attribute number of oid column */
    -	AttrNumber	attnum_name;	/* attnum of name field */
    -	AttrNumber	attnum_namespace;	/* attnum of namespace field */
    -	AttrNumber	attnum_owner;	/* attnum of owner field */
    -	AttrNumber	attnum_acl;		/* attnum of acl field */
    +	AttrNumber	attnum_name;	/* attphysnum of name field */
    +	AttrNumber	attnum_namespace;	/* attphysnum of namespace field */
    +	AttrNumber	attnum_owner;	/* attphysnum of owner field */
    +	AttrNumber	attnum_acl;		/* attphysnum of acl field */
     	ObjectType	objtype;		/* OBJECT_* of this object type */
     	bool		is_nsp_name_unique; /* can the nsp/name combination (or name
     									 * alone, if there's no namespace) be
    @@ -1520,7 +1520,7 @@ get_object_address_attribute(ObjectType objtype, List *object,
     	Oid			reloid;
     	Relation	relation;
     	const char *attname;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     
     	/* Extract relation name and open relation. */
     	if (list_length(object) < 2)
    @@ -1534,8 +1534,8 @@ get_object_address_attribute(ObjectType objtype, List *object,
     	reloid = RelationGetRelid(relation);
     
     	/* Look up attribute and construct return value. */
    -	attnum = get_attnum(reloid, attname);
    -	if (attnum == InvalidAttrNumber)
    +	attphysnum = get_attphysnum(reloid, attname);
    +	if (attphysnum == InvalidAttrNumber)
     	{
     		if (!missing_ok)
     			ereport(ERROR,
    @@ -1552,7 +1552,7 @@ get_object_address_attribute(ObjectType objtype, List *object,
     
     	address.classId = RelationRelationId;
     	address.objectId = reloid;
    -	address.objectSubId = attnum;
    +	address.objectSubId = attphysnum;
     
     	*relp = relation;
     	return address;
    @@ -1571,7 +1571,7 @@ get_object_address_attrdef(ObjectType objtype, List *object,
     	Oid			reloid;
     	Relation	relation;
     	const char *attname;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	TupleDesc	tupdesc;
     	Oid			defoid;
     
    @@ -1589,10 +1589,10 @@ get_object_address_attrdef(ObjectType objtype, List *object,
     	tupdesc = RelationGetDescr(relation);
     
     	/* Look up attribute number and fetch the pg_attrdef OID */
    -	attnum = get_attnum(reloid, attname);
    +	attphysnum = get_attphysnum(reloid, attname);
     	defoid = InvalidOid;
    -	if (attnum != InvalidAttrNumber && tupdesc->constr != NULL)
    -		defoid = GetAttrDefaultOid(reloid, attnum);
    +	if (attphysnum != InvalidAttrNumber && tupdesc->constr != NULL)
    +		defoid = GetAttrDefaultOid(reloid, attphysnum);
     	if (!OidIsValid(defoid))
     	{
     		if (!missing_ok)
    diff --git a/src/backend/catalog/pg_attrdef.c b/src/backend/catalog/pg_attrdef.c
    index c5d4a9912e..8587796e0b 100644
    --- a/src/backend/catalog/pg_attrdef.c
    +++ b/src/backend/catalog/pg_attrdef.c
    @@ -32,7 +32,7 @@
     
     
     /*
    - * Store a default expression for column attnum of relation rel.
    + * Store a default expression for column attphysnum of relation rel.
      *
      * Returns the OID of the new pg_attrdef tuple.
      *
    @@ -43,7 +43,7 @@
      * in effect be changing existing tuples.
      */
     Oid
    -StoreAttrDefault(Relation rel, AttrNumber attnum,
    +StoreAttrDefault(Relation rel, AttrNumber attphysnum,
     				 Node *expr, bool is_internal, bool add_column_mode)
     {
     	char	   *adbin;
    @@ -73,7 +73,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
     									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_adnum - 1] = attphysnum;
     	values[Anum_pg_attrdef_adbin - 1] = CStringGetTextDatum(adbin);
     
     	tuple = heap_form_tuple(adrel->rd_att, values, nulls);
    @@ -95,12 +95,12 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
     	 * exists.
     	 */
     	attrrel = table_open(AttributeRelationId, RowExclusiveLock);
    -	atttup = SearchSysCacheCopy2(ATTNUM,
    +	atttup = SearchSysCacheCopy2(ATTPHYSNUM,
     								 ObjectIdGetDatum(RelationGetRelid(rel)),
    -								 Int16GetDatum(attnum));
    +								 Int16GetDatum(attphysnum));
     	if (!HeapTupleIsValid(atttup))
     		elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -			 attnum, RelationGetRelid(rel));
    +			 attphysnum, RelationGetRelid(rel));
     	attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
     	attgenerated = attStruct->attgenerated;
     	if (!attStruct->atthasdef)
    @@ -136,7 +136,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
     
     			FreeExecutorState(estate);
     
    -			defAttStruct = TupleDescAttr(rel->rd_att, attnum - 1);
    +			defAttStruct = TupleDescAttr(rel->rd_att, attphysnum - 1);
     
     			if (missingIsNull)
     			{
    @@ -179,7 +179,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
     	 */
     	colobject.classId = RelationRelationId;
     	colobject.objectId = RelationGetRelid(rel);
    -	colobject.objectSubId = attnum;
    +	colobject.objectSubId = attphysnum;
     
     	recordDependencyOn(&defobject, &colobject,
     					   attgenerated ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO);
    @@ -200,7 +200,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
     	 * needs to distinguish.
     	 */
     	InvokeObjectPostCreateHookArg(AttrDefaultRelationId,
    -								  RelationGetRelid(rel), attnum, is_internal);
    +								  RelationGetRelid(rel), attphysnum, is_internal);
     
     	return attrdefOid;
     }
    @@ -213,7 +213,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
      * (If no default, raise error if complain is true, else return quietly.)
      */
     void
    -RemoveAttrDefault(Oid relid, AttrNumber attnum,
    +RemoveAttrDefault(Oid relid, AttrNumber attphysnum,
     				  DropBehavior behavior, bool complain, bool internal)
     {
     	Relation	attrdef_rel;
    @@ -231,7 +231,7 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum,
     	ScanKeyInit(&scankeys[1],
     				Anum_pg_attrdef_adnum,
     				BTEqualStrategyNumber, F_INT2EQ,
    -				Int16GetDatum(attnum));
    +				Int16GetDatum(attphysnum));
     
     	scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true,
     							  NULL, 2, scankeys);
    @@ -256,8 +256,8 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum,
     	table_close(attrdef_rel, RowExclusiveLock);
     
     	if (complain && !found)
    -		elog(ERROR, "could not find attrdef tuple for relation %u attnum %d",
    -			 relid, attnum);
    +		elog(ERROR, "could not find attrdef tuple for relation %u attphysnum %d",
    +			 relid, attphysnum);
     }
     
     /*
    @@ -310,7 +310,7 @@ RemoveAttrDefaultById(Oid attrdefId)
     	/* Fix the pg_attribute row */
     	attr_rel = table_open(AttributeRelationId, RowExclusiveLock);
     
    -	tuple = SearchSysCacheCopy2(ATTNUM,
    +	tuple = SearchSysCacheCopy2(ATTPHYSNUM,
     								ObjectIdGetDatum(myrelid),
     								Int16GetDatum(myattnum));
     	if (!HeapTupleIsValid(tuple))	/* shouldn't happen */
    @@ -339,7 +339,7 @@ RemoveAttrDefaultById(Oid attrdefId)
      * Returns InvalidOid if there is no such pg_attrdef entry.
      */
     Oid
    -GetAttrDefaultOid(Oid relid, AttrNumber attnum)
    +GetAttrDefaultOid(Oid relid, AttrNumber attphysnum)
     {
     	Oid			result = InvalidOid;
     	Relation	attrdef;
    @@ -357,7 +357,7 @@ GetAttrDefaultOid(Oid relid, AttrNumber attnum)
     				Anum_pg_attrdef_adnum,
     				BTEqualStrategyNumber,
     				F_INT2EQ,
    -				Int16GetDatum(attnum));
    +				Int16GetDatum(attphysnum));
     	scan = systable_beginscan(attrdef, AttrDefaultIndexId, true,
     							  NULL, 2, keys);
     
    diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
    index e86e5e6898..e8a2be6fc7 100644
    --- a/src/backend/catalog/pg_depend.c
    +++ b/src/backend/catalog/pg_depend.c
    @@ -816,7 +816,7 @@ sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId)
      * with the specified dependency type.
      */
     static List *
    -getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
    +getOwnedSequences_internal(Oid relid, AttrNumber attphysnum, char deptype)
     {
     	List	   *result = NIL;
     	Relation	depRel;
    @@ -834,14 +834,14 @@ getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
     				Anum_pg_depend_refobjid,
     				BTEqualStrategyNumber, F_OIDEQ,
     				ObjectIdGetDatum(relid));
    -	if (attnum)
    +	if (attphysnum)
     		ScanKeyInit(&key[2],
     					Anum_pg_depend_refobjsubid,
     					BTEqualStrategyNumber, F_INT4EQ,
    -					Int32GetDatum(attnum));
    +					Int32GetDatum(attphysnum));
     
     	scan = systable_beginscan(depRel, DependReferenceIndexId, true,
    -							  NULL, attnum ? 3 : 2, key);
    +							  NULL, attphysnum ? 3 : 2, key);
     
     	while (HeapTupleIsValid(tup = systable_getnext(scan)))
     	{
    @@ -884,9 +884,9 @@ getOwnedSequences(Oid relid)
      * Get owned identity sequence, error if not exactly one.
      */
     Oid
    -getIdentitySequence(Oid relid, AttrNumber attnum, bool missing_ok)
    +getIdentitySequence(Oid relid, AttrNumber attphysnum, bool missing_ok)
     {
    -	List	   *seqlist = getOwnedSequences_internal(relid, attnum, DEPENDENCY_INTERNAL);
    +	List	   *seqlist = getOwnedSequences_internal(relid, attphysnum, DEPENDENCY_INTERNAL);
     
     	if (list_length(seqlist) > 1)
     		elog(ERROR, "more than one owned sequence found");
    diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
    index c365de3a72..0a8cefe637 100644
    --- a/src/backend/catalog/pg_publication.c
    +++ b/src/backend/catalog/pg_publication.c
    @@ -502,34 +502,34 @@ publication_translate_columns(Relation targetrel, List *columns,
     	foreach(lc, columns)
     	{
     		char	   *colname = strVal(lfirst(lc));
    -		AttrNumber	attnum = get_attnum(RelationGetRelid(targetrel), colname);
    +		AttrNumber	attphysnum = get_attphysnum(RelationGetRelid(targetrel), colname);
     
    -		if (attnum == InvalidAttrNumber)
    +		if (attphysnum == InvalidAttrNumber)
     			ereport(ERROR,
     					errcode(ERRCODE_UNDEFINED_COLUMN),
     					errmsg("column \"%s\" of relation \"%s\" does not exist",
     						   colname, RelationGetRelationName(targetrel)));
     
    -		if (!AttrNumberIsForUserDefinedAttr(attnum))
    +		if (!AttrNumberIsForUserDefinedAttr(attphysnum))
     			ereport(ERROR,
     					errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     					errmsg("cannot reference system column \"%s\" in publication column list",
     						   colname));
     
    -		if (TupleDescAttr(tupdesc, attnum - 1)->attgenerated)
    +		if (TupleDescAttr(tupdesc, attphysnum - 1)->attgenerated)
     			ereport(ERROR,
     					errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     					errmsg("cannot reference generated column \"%s\" in publication column list",
     						   colname));
     
    -		if (bms_is_member(attnum, set))
    +		if (bms_is_member(attphysnum, set))
     			ereport(ERROR,
     					errcode(ERRCODE_DUPLICATE_OBJECT),
     					errmsg("duplicate column \"%s\" in publication column list",
     						   colname));
     
    -		set = bms_add_member(set, attnum);
    -		attarray[n++] = attnum;
    +		set = bms_add_member(set, attphysnum);
    +		attarray[n++] = attphysnum;
     	}
     
     	/* Be tidy, so that the catalog representation is always sorted */
    diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
    index fedaed533b..37b7edc2db 100644
    --- a/src/backend/catalog/system_views.sql
    +++ b/src/backend/catalog/system_views.sql
    @@ -245,10 +245,10 @@ CREATE VIEW pg_stats WITH (security_barrier) AS
                 WHEN stakind5 = 5 THEN stanumbers5
             END AS elem_count_histogram
         FROM pg_statistic s JOIN pg_class c ON (c.oid = s.starelid)
    -         JOIN pg_attribute a ON (c.oid = attrelid AND attnum = s.staattnum)
    +         JOIN pg_attribute a ON (c.oid = attrelid AND attphysnum = s.staattnum)
              LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
         WHERE NOT attisdropped
    -    AND has_column_privilege(c.oid, a.attnum, 'select')
    +    AND has_column_privilege(c.oid, a.attphysnum, 'select')
         AND (c.relrowsecurity = false OR NOT row_security_active(c.oid));
     
     REVOKE ALL ON pg_statistic FROM public;
    @@ -259,10 +259,10 @@ CREATE VIEW pg_stats_ext WITH (security_barrier) AS
                sn.nspname AS statistics_schemaname,
                s.stxname AS statistics_name,
                pg_get_userbyid(s.stxowner) AS statistics_owner,
    -           ( SELECT array_agg(a.attname ORDER BY a.attnum)
    +           ( SELECT array_agg(a.attname ORDER BY a.attphysnum)
                  FROM unnest(s.stxkeys) k
                       JOIN pg_attribute a
    -                       ON (a.attrelid = s.stxrelid AND a.attnum = k)
    +                       ON (a.attrelid = s.stxrelid AND a.attphysnum = k)
                ) AS attnames,
                pg_get_statisticsobjdef_expressions(s.oid) as exprs,
                s.stxkind AS kinds,
    @@ -288,8 +288,8 @@ CREATE VIEW pg_stats_ext WITH (security_barrier) AS
                   ( SELECT 1
                     FROM unnest(stxkeys) k
                          JOIN pg_attribute a
    -                          ON (a.attrelid = s.stxrelid AND a.attnum = k)
    -                WHERE NOT has_column_privilege(c.oid, a.attnum, 'select') )
    +                          ON (a.attrelid = s.stxrelid AND a.attphysnum = k)
    +                WHERE NOT has_column_privilege(c.oid, a.attphysnum, 'select') )
         AND (c.relrowsecurity = false OR NOT row_security_active(c.oid));
     
     CREATE VIEW pg_stats_ext_exprs WITH (security_barrier) AS
    @@ -369,12 +369,12 @@ CREATE VIEW pg_publication_tables AS
             P.pubname AS pubname,
             N.nspname AS schemaname,
             C.relname AS tablename,
    -        ( SELECT array_agg(a.attname ORDER BY a.attnum)
    +        ( SELECT array_agg(a.attname ORDER BY a.attphysnum)
               FROM unnest(CASE WHEN GPT.attrs IS NOT NULL THEN GPT.attrs
                           ELSE (SELECT array_agg(g) FROM generate_series(1, C.relnatts) g)
                           END) k
                    JOIN pg_attribute a
    -                    ON (a.attrelid = GPT.relid AND a.attnum = k)
    +                    ON (a.attrelid = GPT.relid AND a.attphysnum = k)
             ) AS attnames,
             pg_get_expr(GPT.qual, GPT.relid) AS rowfilter
         FROM pg_publication P,
    @@ -446,7 +446,7 @@ FROM
         pg_seclabel l
         JOIN pg_class rel ON l.classoid = rel.tableoid AND l.objoid = rel.oid
         JOIN pg_attribute att
    -         ON rel.oid = att.attrelid AND l.objsubid = att.attnum
    +         ON rel.oid = att.attrelid AND l.objsubid = att.attphysnum
         JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
     WHERE
         l.objsubid != 0
    diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
    index 2da6b75a15..fe0b81d99e 100644
    --- a/src/backend/commands/analyze.c
    +++ b/src/backend/commands/analyze.c
    @@ -95,7 +95,7 @@ static void compute_index_stats(Relation onerel, double totalrows,
     								AnlIndexData *indexdata, int nindexes,
     								HeapTuple *rows, int numrows,
     								MemoryContext col_context);
    -static VacAttrStats *examine_attribute(Relation onerel, int attnum,
    +static VacAttrStats *examine_attribute(Relation onerel, int attphysnum,
     									   Node *index_expr);
     static int	acquire_sample_rows(Relation onerel, int elevel,
     								HeapTuple *rows, int targrows,
    @@ -574,7 +574,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
     			 * If the appropriate flavor of the n_distinct option is
     			 * specified, override with the corresponding value.
     			 */
    -			aopt = get_attribute_options(onerel->rd_id, stats->attr->attnum);
    +			aopt = get_attribute_options(onerel->rd_id, stats->attr->attphysnum);
     			if (aopt != NULL)
     			{
     				float8		n_distinct;
    @@ -928,16 +928,16 @@ compute_index_stats(Relation onerel, double totalrows,
     				for (i = 0; i < attr_cnt; i++)
     				{
     					VacAttrStats *stats = thisdata->vacattrstats[i];
    -					int			attnum = stats->attr->attnum;
    +					int			attphysnum = stats->attr->attphysnum;
     
    -					if (isnull[attnum - 1])
    +					if (isnull[attphysnum - 1])
     					{
     						exprvals[tcnt] = (Datum) 0;
     						exprnulls[tcnt] = true;
     					}
     					else
     					{
    -						exprvals[tcnt] = datumCopy(values[attnum - 1],
    +						exprvals[tcnt] = datumCopy(values[attphysnum - 1],
     												   stats->attrtype->typbyval,
     												   stats->attrtype->typlen);
     						exprnulls[tcnt] = false;
    @@ -998,9 +998,9 @@ compute_index_stats(Relation onerel, double totalrows,
      * and index_expr is the expression tree representing the column's data.
      */
     static VacAttrStats *
    -examine_attribute(Relation onerel, int attnum, Node *index_expr)
    +examine_attribute(Relation onerel, int attphysnum, Node *index_expr)
     {
    -	Form_pg_attribute attr = TupleDescAttr(onerel->rd_att, attnum - 1);
    +	Form_pg_attribute attr = TupleDescAttr(onerel->rd_att, attphysnum - 1);
     	HeapTuple	typtuple;
     	VacAttrStats *stats;
     	int			i;
    @@ -1041,8 +1041,8 @@ examine_attribute(Relation onerel, int attnum, Node *index_expr)
     		 * preference to anything else; but if not, fall back to whatever we
     		 * can get from the expression.
     		 */
    -		if (OidIsValid(onerel->rd_indcollation[attnum - 1]))
    -			stats->attrcollid = onerel->rd_indcollation[attnum - 1];
    +		if (OidIsValid(onerel->rd_indcollation[attphysnum - 1]))
    +			stats->attrcollid = onerel->rd_indcollation[attphysnum - 1];
     		else
     			stats->attrcollid = exprCollation(index_expr);
     	}
    @@ -1059,7 +1059,7 @@ examine_attribute(Relation onerel, int attnum, Node *index_expr)
     		elog(ERROR, "cache lookup failed for type %u", stats->attrtypid);
     	stats->attrtype = (Form_pg_type) GETSTRUCT(typtuple);
     	stats->anl_context = anl_context;
    -	stats->tupattnum = attnum;
    +	stats->tupattnum = attphysnum;
     
     	/*
     	 * The fields describing the stats->stavalues[n] element types default to
    @@ -1656,7 +1656,7 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats)
     		}
     
     		values[Anum_pg_statistic_starelid - 1] = ObjectIdGetDatum(relid);
    -		values[Anum_pg_statistic_staattnum - 1] = Int16GetDatum(stats->attr->attnum);
    +		values[Anum_pg_statistic_staattnum - 1] = Int16GetDatum(stats->attr->attphysnum);
     		values[Anum_pg_statistic_stainherit - 1] = BoolGetDatum(inh);
     		values[Anum_pg_statistic_stanullfrac - 1] = Float4GetDatum(stats->stanullfrac);
     		values[Anum_pg_statistic_stawidth - 1] = Int32GetDatum(stats->stawidth);
    @@ -1725,7 +1725,7 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats)
     		/* Is there already a pg_statistic tuple for this attribute? */
     		oldtup = SearchSysCache3(STATRELATTINH,
     								 ObjectIdGetDatum(relid),
    -								 Int16GetDatum(stats->attr->attnum),
    +								 Int16GetDatum(stats->attr->attphysnum),
     								 BoolGetDatum(inh));
     
     		if (HeapTupleIsValid(oldtup))
    @@ -1761,11 +1761,11 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats)
     static Datum
     std_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull)
     {
    -	int			attnum = stats->tupattnum;
    +	int			attphysnum = stats->tupattnum;
     	HeapTuple	tuple = stats->rows[rownum];
     	TupleDesc	tupDesc = stats->tupDesc;
     
    -	return heap_getattr(tuple, attnum, tupDesc, isNull);
    +	return heap_getattr(tuple, attphysnum, tupDesc, isNull);
     }
     
     /*
    diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
    index e2870e3c11..6b15837dba 100644
    --- a/src/backend/commands/copy.c
    +++ b/src/backend/commands/copy.c
    @@ -739,11 +739,11 @@ CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
     		foreach(l, attnamelist)
     		{
     			char	   *name = strVal(lfirst(l));
    -			int			attnum;
    +			int			attphysnum;
     			int			i;
     
     			/* Lookup column name */
    -			attnum = InvalidAttrNumber;
    +			attphysnum = InvalidAttrNumber;
     			for (i = 0; i < tupDesc->natts; i++)
     			{
     				Form_pg_attribute att = TupleDescAttr(tupDesc, i);
    @@ -758,11 +758,11 @@ CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
     								 errmsg("column \"%s\" is a generated column",
     										name),
     								 errdetail("Generated columns cannot be used in COPY.")));
    -					attnum = att->attnum;
    +					attphysnum = att->attphysnum;
     					break;
     				}
     			}
    -			if (attnum == InvalidAttrNumber)
    +			if (attphysnum == InvalidAttrNumber)
     			{
     				if (rel != NULL)
     					ereport(ERROR,
    @@ -776,12 +776,12 @@ CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist)
     									name)));
     			}
     			/* Check for duplicates */
    -			if (list_member_int(attnums, attnum))
    +			if (list_member_int(attnums, attphysnum))
     				ereport(ERROR,
     						(errcode(ERRCODE_DUPLICATE_COLUMN),
     						 errmsg("column \"%s\" specified more than once",
     								name)));
    -			attnums = lappend_int(attnums, attnum);
    +			attnums = lappend_int(attnums, attphysnum);
     		}
     	}
     
    diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
    index 35a1d3a774..ca44d12b11 100644
    --- a/src/backend/commands/copyfrom.c
    +++ b/src/backend/commands/copyfrom.c
    @@ -1202,7 +1202,7 @@ BeginCopyFrom(ParseState *pstate,
     				num_defaults;
     	FmgrInfo   *in_functions;
     	Oid		   *typioparams;
    -	int			attnum;
    +	int			attphysnum;
     	Oid			in_func_oid;
     	int		   *defmap;
     	ExprState **defexprs;
    @@ -1258,15 +1258,15 @@ BeginCopyFrom(ParseState *pstate,
     
     		foreach(cur, attnums)
     		{
    -			int			attnum = lfirst_int(cur);
    -			Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
    +			int			attphysnum = lfirst_int(cur);
    +			Form_pg_attribute attr = TupleDescAttr(tupDesc, attphysnum - 1);
     
    -			if (!list_member_int(cstate->attnumlist, attnum))
    +			if (!list_member_int(cstate->attnumlist, attphysnum))
     				ereport(ERROR,
     						(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     						 errmsg("FORCE_NOT_NULL column \"%s\" not referenced by COPY",
     								NameStr(attr->attname))));
    -			cstate->opts.force_notnull_flags[attnum - 1] = true;
    +			cstate->opts.force_notnull_flags[attphysnum - 1] = true;
     		}
     	}
     
    @@ -1281,15 +1281,15 @@ BeginCopyFrom(ParseState *pstate,
     
     		foreach(cur, attnums)
     		{
    -			int			attnum = lfirst_int(cur);
    -			Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
    +			int			attphysnum = lfirst_int(cur);
    +			Form_pg_attribute attr = TupleDescAttr(tupDesc, attphysnum - 1);
     
    -			if (!list_member_int(cstate->attnumlist, attnum))
    +			if (!list_member_int(cstate->attnumlist, attphysnum))
     				ereport(ERROR,
     						(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     						 errmsg("FORCE_NULL column \"%s\" not referenced by COPY",
     								NameStr(attr->attname))));
    -			cstate->opts.force_null_flags[attnum - 1] = true;
    +			cstate->opts.force_null_flags[attphysnum - 1] = true;
     		}
     	}
     
    @@ -1305,15 +1305,15 @@ BeginCopyFrom(ParseState *pstate,
     
     		foreach(cur, attnums)
     		{
    -			int			attnum = lfirst_int(cur);
    -			Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
    +			int			attphysnum = lfirst_int(cur);
    +			Form_pg_attribute attr = TupleDescAttr(tupDesc, attphysnum - 1);
     
    -			if (!list_member_int(cstate->attnumlist, attnum))
    +			if (!list_member_int(cstate->attnumlist, attphysnum))
     				ereport(ERROR,
     						(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     						 errmsg_internal("selected column \"%s\" not referenced by COPY",
     										 NameStr(attr->attname))));
    -			cstate->convert_select_flags[attnum - 1] = true;
    +			cstate->convert_select_flags[attphysnum - 1] = true;
     		}
     	}
     
    @@ -1401,9 +1401,9 @@ BeginCopyFrom(ParseState *pstate,
     	defmap = (int *) palloc(num_phys_attrs * sizeof(int));
     	defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *));
     
    -	for (attnum = 1; attnum <= num_phys_attrs; attnum++)
    +	for (attphysnum = 1; attphysnum <= num_phys_attrs; attphysnum++)
     	{
    -		Form_pg_attribute att = TupleDescAttr(tupDesc, attnum - 1);
    +		Form_pg_attribute att = TupleDescAttr(tupDesc, attphysnum - 1);
     
     		/* We don't need info for dropped attributes */
     		if (att->attisdropped)
    @@ -1412,19 +1412,19 @@ BeginCopyFrom(ParseState *pstate,
     		/* Fetch the input function and typioparam info */
     		if (cstate->opts.binary)
     			getTypeBinaryInputInfo(att->atttypid,
    -								   &in_func_oid, &typioparams[attnum - 1]);
    +								   &in_func_oid, &typioparams[attphysnum - 1]);
     		else
     			getTypeInputInfo(att->atttypid,
    -							 &in_func_oid, &typioparams[attnum - 1]);
    -		fmgr_info(in_func_oid, &in_functions[attnum - 1]);
    +							 &in_func_oid, &typioparams[attphysnum - 1]);
    +		fmgr_info(in_func_oid, &in_functions[attphysnum - 1]);
     
     		/* Get default info if needed */
    -		if (!list_member_int(cstate->attnumlist, attnum) && !att->attgenerated)
    +		if (!list_member_int(cstate->attnumlist, attphysnum) && !att->attgenerated)
     		{
     			/* attribute is NOT to be copied from input */
     			/* use default value if one exists */
     			Expr	   *defexpr = (Expr *) build_column_default(cstate->rel,
    -																attnum);
    +																attphysnum);
     
     			if (defexpr != NULL)
     			{
    @@ -1433,7 +1433,7 @@ BeginCopyFrom(ParseState *pstate,
     
     				/* Initialize executable expression in copycontext */
     				defexprs[num_defaults] = ExecInitExpr(defexpr, NULL);
    -				defmap[num_defaults] = attnum - 1;
    +				defmap[num_defaults] = attphysnum - 1;
     				num_defaults++;
     
     				/*
    diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c
    index 57813b3458..e9b0b294e9 100644
    --- a/src/backend/commands/copyfromparse.c
    +++ b/src/backend/commands/copyfromparse.c
    @@ -788,9 +788,9 @@ NextCopyFromRawFields(CopyFromState cstate, char ***fields, int *nfields)
     			fldnum = 0;
     			foreach(cur, cstate->attnumlist)
     			{
    -				int			attnum = lfirst_int(cur);
    +				int			attphysnum = lfirst_int(cur);
     				char	   *colName;
    -				Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
    +				Form_pg_attribute attr = TupleDescAttr(tupDesc, attphysnum - 1);
     
     				Assert(fldnum < cstate->max_fields);
     
    @@ -894,8 +894,8 @@ NextCopyFrom(CopyFromState cstate, ExprContext *econtext,
     		/* Loop to read the user attributes on the line. */
     		foreach(cur, cstate->attnumlist)
     		{
    -			int			attnum = lfirst_int(cur);
    -			int			m = attnum - 1;
    +			int			attphysnum = lfirst_int(cur);
    +			int			m = attphysnum - 1;
     			Form_pg_attribute att = TupleDescAttr(tupDesc, m);
     
     			if (fieldno >= fldct)
    @@ -991,8 +991,8 @@ NextCopyFrom(CopyFromState cstate, ExprContext *econtext,
     
     		foreach(cur, cstate->attnumlist)
     		{
    -			int			attnum = lfirst_int(cur);
    -			int			m = attnum - 1;
    +			int			attphysnum = lfirst_int(cur);
    +			int			m = attphysnum - 1;
     			Form_pg_attribute att = TupleDescAttr(tupDesc, m);
     
     			cstate->cur_attname = NameStr(att->attname);
    diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c
    index fca29a9a10..e0306cc11b 100644
    --- a/src/backend/commands/copyto.c
    +++ b/src/backend/commands/copyto.c
    @@ -579,15 +579,15 @@ BeginCopyTo(ParseState *pstate,
     
     		foreach(cur, attnums)
     		{
    -			int			attnum = lfirst_int(cur);
    -			Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
    +			int			attphysnum = lfirst_int(cur);
    +			Form_pg_attribute attr = TupleDescAttr(tupDesc, attphysnum - 1);
     
    -			if (!list_member_int(cstate->attnumlist, attnum))
    +			if (!list_member_int(cstate->attnumlist, attphysnum))
     				ereport(ERROR,
     						(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     						 errmsg("FORCE_QUOTE column \"%s\" not referenced by COPY",
     								NameStr(attr->attname))));
    -			cstate->opts.force_quote_flags[attnum - 1] = true;
    +			cstate->opts.force_quote_flags[attphysnum - 1] = true;
     		}
     	}
     
    @@ -602,15 +602,15 @@ BeginCopyTo(ParseState *pstate,
     
     		foreach(cur, attnums)
     		{
    -			int			attnum = lfirst_int(cur);
    -			Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
    +			int			attphysnum = lfirst_int(cur);
    +			Form_pg_attribute attr = TupleDescAttr(tupDesc, attphysnum - 1);
     
    -			if (!list_member_int(cstate->attnumlist, attnum))
    +			if (!list_member_int(cstate->attnumlist, attphysnum))
     				ereport(ERROR,
     						(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     						 errmsg("FORCE_NOT_NULL column \"%s\" not referenced by COPY",
     								NameStr(attr->attname))));
    -			cstate->opts.force_notnull_flags[attnum - 1] = true;
    +			cstate->opts.force_notnull_flags[attphysnum - 1] = true;
     		}
     	}
     
    @@ -625,15 +625,15 @@ BeginCopyTo(ParseState *pstate,
     
     		foreach(cur, attnums)
     		{
    -			int			attnum = lfirst_int(cur);
    -			Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
    +			int			attphysnum = lfirst_int(cur);
    +			Form_pg_attribute attr = TupleDescAttr(tupDesc, attphysnum - 1);
     
    -			if (!list_member_int(cstate->attnumlist, attnum))
    +			if (!list_member_int(cstate->attnumlist, attphysnum))
     				ereport(ERROR,
     						(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     						 errmsg("FORCE_NULL column \"%s\" not referenced by COPY",
     								NameStr(attr->attname))));
    -			cstate->opts.force_null_flags[attnum - 1] = true;
    +			cstate->opts.force_null_flags[attphysnum - 1] = true;
     		}
     	}
     
    @@ -793,10 +793,10 @@ DoCopyTo(CopyToState cstate)
     	cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
     	foreach(cur, cstate->attnumlist)
     	{
    -		int			attnum = lfirst_int(cur);
    +		int			attphysnum = lfirst_int(cur);
     		Oid			out_func_oid;
     		bool		isvarlena;
    -		Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1);
    +		Form_pg_attribute attr = TupleDescAttr(tupDesc, attphysnum - 1);
     
     		if (cstate->opts.binary)
     			getTypeBinaryOutputInfo(attr->atttypid,
    @@ -806,7 +806,7 @@ DoCopyTo(CopyToState cstate)
     			getTypeOutputInfo(attr->atttypid,
     							  &out_func_oid,
     							  &isvarlena);
    -		fmgr_info(out_func_oid, &cstate->out_functions[attnum - 1]);
    +		fmgr_info(out_func_oid, &cstate->out_functions[attphysnum - 1]);
     	}
     
     	/*
    @@ -851,14 +851,14 @@ DoCopyTo(CopyToState cstate)
     
     			foreach(cur, cstate->attnumlist)
     			{
    -				int			attnum = lfirst_int(cur);
    +				int			attphysnum = lfirst_int(cur);
     				char	   *colname;
     
     				if (hdr_delim)
     					CopySendChar(cstate, cstate->opts.delim[0]);
     				hdr_delim = true;
     
    -				colname = NameStr(TupleDescAttr(tupDesc, attnum - 1)->attname);
    +				colname = NameStr(TupleDescAttr(tupDesc, attphysnum - 1)->attname);
     
     				if (cstate->opts.csv_mode)
     					CopyAttributeOutCSV(cstate, colname, false,
    @@ -950,9 +950,9 @@ CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
     
     	foreach(cur, cstate->attnumlist)
     	{
    -		int			attnum = lfirst_int(cur);
    -		Datum		value = slot->tts_values[attnum - 1];
    -		bool		isnull = slot->tts_isnull[attnum - 1];
    +		int			attphysnum = lfirst_int(cur);
    +		Datum		value = slot->tts_values[attphysnum - 1];
    +		bool		isnull = slot->tts_isnull[attphysnum - 1];
     
     		if (!cstate->opts.binary)
     		{
    @@ -972,11 +972,11 @@ CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
     		{
     			if (!cstate->opts.binary)
     			{
    -				string = OutputFunctionCall(&out_functions[attnum - 1],
    +				string = OutputFunctionCall(&out_functions[attphysnum - 1],
     											value);
     				if (cstate->opts.csv_mode)
     					CopyAttributeOutCSV(cstate, string,
    -										cstate->opts.force_quote_flags[attnum - 1],
    +										cstate->opts.force_quote_flags[attphysnum - 1],
     										list_length(cstate->attnumlist) == 1);
     				else
     					CopyAttributeOutText(cstate, string);
    @@ -985,7 +985,7 @@ CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
     			{
     				bytea	   *outputbytes;
     
    -				outputbytes = SendFunctionCall(&out_functions[attnum - 1],
    +				outputbytes = SendFunctionCall(&out_functions[attphysnum - 1],
     											   value);
     				CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ);
     				CopySendData(cstate, VARDATA(outputbytes),
    diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
    index 9abbb6b555..ec046d77cf 100644
    --- a/src/backend/commands/createas.c
    +++ b/src/backend/commands/createas.c
    @@ -453,7 +453,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
     	ObjectAddress intoRelationAddr;
     	Relation	intoRelationDesc;
     	ListCell   *lc;
    -	int			attnum;
    +	int			attphysnum;
     
     	Assert(into != NULL);		/* else somebody forgot to set it */
     
    @@ -468,9 +468,9 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
     	 */
     	attrList = NIL;
     	lc = list_head(into->colNames);
    -	for (attnum = 0; attnum < typeinfo->natts; attnum++)
    +	for (attphysnum = 0; attphysnum < typeinfo->natts; attphysnum++)
     	{
    -		Form_pg_attribute attribute = TupleDescAttr(typeinfo, attnum);
    +		Form_pg_attribute attribute = TupleDescAttr(typeinfo, attphysnum);
     		ColumnDef  *col;
     		char	   *colname;
     
    diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
    index 4642527881..2b3dbfbcb1 100644
    --- a/src/backend/commands/event_trigger.c
    +++ b/src/backend/commands/event_trigger.c
    @@ -1211,14 +1211,14 @@ EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool no
     
     		if (tuple)
     		{
    -			AttrNumber	attnum;
    +			AttrNumber	attphysnum;
     			Datum		datum;
     			bool		isnull;
     
    -			attnum = get_object_attnum_namespace(obj->address.classId);
    -			if (attnum != InvalidAttrNumber)
    +			attphysnum = get_object_attnum_namespace(obj->address.classId);
    +			if (attphysnum != InvalidAttrNumber)
     			{
    -				datum = heap_getattr(tuple, attnum,
    +				datum = heap_getattr(tuple, attphysnum,
     									 RelationGetDescr(catalog), &isnull);
     				if (!isnull)
     				{
    @@ -1249,10 +1249,10 @@ EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool no
     			if (get_object_namensp_unique(obj->address.classId) &&
     				obj->address.objectSubId == 0)
     			{
    -				attnum = get_object_attnum_name(obj->address.classId);
    -				if (attnum != InvalidAttrNumber)
    +				attphysnum = get_object_attnum_name(obj->address.classId);
    +				if (attphysnum != InvalidAttrNumber)
     				{
    -					datum = heap_getattr(tuple, attnum,
    +					datum = heap_getattr(tuple, attphysnum,
     										 RelationGetDescr(catalog), &isnull);
     					if (!isnull)
     						obj->objname = pstrdup(NameStr(*DatumGetName(datum)));
    diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
    index eac13ac0b7..52e2aa87c6 100644
    --- a/src/backend/commands/indexcmds.c
    +++ b/src/backend/commands/indexcmds.c
    @@ -1798,7 +1798,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
     									attribute->name)));
     			}
     			attform = (Form_pg_attribute) GETSTRUCT(atttuple);
    -			indexInfo->ii_IndexAttrNumbers[attn] = attform->attnum;
    +			indexInfo->ii_IndexAttrNumbers[attn] = attform->attphysnum;
     			atttype = attform->atttypid;
     			attcollation = attform->attcollation;
     			ReleaseSysCache(atttuple);
    diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
    index d1ee106465..47ea6f6246 100644
    --- a/src/backend/commands/matview.c
    +++ b/src/backend/commands/matview.c
    @@ -705,9 +705,9 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
     			/* Add quals for all columns from this index. */
     			for (i = 0; i < indnkeyatts; i++)
     			{
    -				int			attnum = indexStruct->indkey.values[i];
    +				int			attphysnum = indexStruct->indkey.values[i];
     				Oid			opclass = indclass->values[i];
    -				Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
    +				Form_pg_attribute attr = TupleDescAttr(tupdesc, attphysnum - 1);
     				Oid			attrtype = attr->atttypid;
     				HeapTuple	cla_ht;
     				Form_pg_opclass cla_tup;
    @@ -747,9 +747,9 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
     				 * that's so unlikely it doesn't seem worth spending extra
     				 * code to avoid.
     				 */
    -				if (opUsedForQual[attnum - 1] == op)
    +				if (opUsedForQual[attphysnum - 1] == op)
     					continue;
    -				opUsedForQual[attnum - 1] = op;
    +				opUsedForQual[attphysnum - 1] = op;
     
     				/*
     				 * Actually add the qual, ANDed with any others.
    @@ -894,9 +894,9 @@ is_usable_unique_index(Relation indexRel)
     
     		for (i = 0; i < numatts; i++)
     		{
    -			int			attnum = indexStruct->indkey.values[i];
    +			int			attphysnum = indexStruct->indkey.values[i];
     
    -			if (attnum <= 0)
    +			if (attphysnum <= 0)
     				return false;
     		}
     		return true;
    diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
    index 8e645741e4..4a4c6ffac5 100644
    --- a/src/backend/commands/publicationcmds.c
    +++ b/src/backend/commands/publicationcmds.c
    @@ -265,7 +265,7 @@ contain_invalid_rfcolumn_walker(Node *node, rf_context *context)
     	if (IsA(node, Var))
     	{
     		Var		   *var = (Var *) node;
    -		AttrNumber	attnum = var->varattno;
    +		AttrNumber	attphysnum = var->varattno;
     
     		/*
     		 * If pubviaroot is true, we are validating the row filter of the
    @@ -275,12 +275,12 @@ contain_invalid_rfcolumn_walker(Node *node, rf_context *context)
     		 */
     		if (context->pubviaroot)
     		{
    -			char	   *colname = get_attname(context->parentid, attnum, false);
    +			char	   *colname = get_attname(context->parentid, attphysnum, false);
     
    -			attnum = get_attnum(context->relid, colname);
    +			attphysnum = get_attphysnum(context->relid, colname);
     		}
     
    -		if (!bms_is_member(attnum - FirstLowInvalidHeapAttributeNumber,
    +		if (!bms_is_member(attphysnum - FirstLowInvalidHeapAttributeNumber,
     						   context->bms_replident))
     			return true;
     	}
    @@ -436,7 +436,7 @@ pub_collist_contains_invalid_column(Oid pubid, Relation relation, List *ancestor
     		x = -1;
     		while ((x = bms_next_member(idattrs, x)) >= 0)
     		{
    -			AttrNumber	attnum = (x + FirstLowInvalidHeapAttributeNumber);
    +			AttrNumber	attphysnum = (x + FirstLowInvalidHeapAttributeNumber);
     
     			/*
     			 * If pubviaroot is true, we are validating the column list of the
    @@ -448,17 +448,17 @@ pub_collist_contains_invalid_column(Oid pubid, Relation relation, List *ancestor
     			if (pubviaroot)
     			{
     				/* attribute name in the child table */
    -				char	   *colname = get_attname(relid, attnum, false);
    +				char	   *colname = get_attname(relid, attphysnum, false);
     
     				/*
    -				 * Determine the attnum for the attribute name in parent (we
    +				 * Determine the attphysnum for the attribute name in parent (we
     				 * are using the column list defined on the parent).
     				 */
    -				attnum = get_attnum(publish_as_relid, colname);
    +				attphysnum = get_attphysnum(publish_as_relid, colname);
     			}
     
     			/* replica identity column, not covered by the column list */
    -			if (!bms_is_member(attnum, columns))
    +			if (!bms_is_member(attphysnum, columns))
     			{
     				result = true;
     				break;
    @@ -1228,9 +1228,9 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup,
     					foreach(lc, newpubrel->columns)
     					{
     						char	   *colname = strVal(lfirst(lc));
    -						AttrNumber	attnum = get_attnum(newrelid, colname);
    +						AttrNumber	attphysnum = get_attphysnum(newrelid, colname);
     
    -						newcolumns = bms_add_member(newcolumns, attnum);
    +						newcolumns = bms_add_member(newcolumns, attphysnum);
     					}
     				}
     
    diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
    index ddf219b21f..0fb47c6d81 100644
    --- a/src/backend/commands/sequence.c
    +++ b/src/backend/commands/sequence.c
    @@ -1595,7 +1595,7 @@ process_owned_by(Relation seqrel, List *owned_by, bool for_identity)
     	DependencyType deptype;
     	int			nnames;
     	Relation	tablerel;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     
     	deptype = for_identity ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO;
     
    @@ -1610,7 +1610,7 @@ process_owned_by(Relation seqrel, List *owned_by, bool for_identity)
     					 errmsg("invalid OWNED BY option"),
     					 errhint("Specify OWNED BY table.column or OWNED BY NONE.")));
     		tablerel = NULL;
    -		attnum = 0;
    +		attphysnum = 0;
     	}
     	else
     	{
    @@ -1648,8 +1648,8 @@ process_owned_by(Relation seqrel, List *owned_by, bool for_identity)
     					 errmsg("sequence must be in same schema as table it is linked to")));
     
     		/* Now, fetch the attribute number from the system cache */
    -		attnum = get_attnum(RelationGetRelid(tablerel), attrname);
    -		if (attnum == InvalidAttrNumber)
    +		attphysnum = get_attphysnum(RelationGetRelid(tablerel), attrname);
    +		if (attphysnum == InvalidAttrNumber)
     			ereport(ERROR,
     					(errcode(ERRCODE_UNDEFINED_COLUMN),
     					 errmsg("column \"%s\" of relation \"%s\" does not exist",
    @@ -1687,7 +1687,7 @@ process_owned_by(Relation seqrel, List *owned_by, bool for_identity)
     
     		refobject.classId = RelationRelationId;
     		refobject.objectId = RelationGetRelid(tablerel);
    -		refobject.objectSubId = attnum;
    +		refobject.objectSubId = attphysnum;
     		depobject.classId = RelationRelationId;
     		depobject.objectId = RelationGetRelid(seqrel);
     		depobject.objectSubId = 0;
    diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
    index 2e716743dd..737ee30e64 100644
    --- a/src/backend/commands/statscmds.c
    +++ b/src/backend/commands/statscmds.c
    @@ -241,7 +241,7 @@ CreateStatistics(CreateStatsStmt *stmt)
     			attForm = (Form_pg_attribute) GETSTRUCT(atttuple);
     
     			/* Disallow use of system attributes in extended stats */
    -			if (attForm->attnum <= 0)
    +			if (attForm->attphysnum <= 0)
     				ereport(ERROR,
     						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     						 errmsg("statistics creation on system columns is not supported")));
    @@ -254,7 +254,7 @@ CreateStatistics(CreateStatsStmt *stmt)
     						 errmsg("column \"%s\" cannot be used in statistics because its type %s has no default btree operator class",
     								attname, format_type_be(attForm->atttypid))));
     
    -			attnums[nattnums] = attForm->attnum;
    +			attnums[nattnums] = attForm->attphysnum;
     			nattnums++;
     			ReleaseSysCache(atttuple);
     		}
    @@ -296,9 +296,9 @@ CreateStatistics(CreateStatsStmt *stmt)
     			k = -1;
     			while ((k = bms_next_member(attnums, k)) >= 0)
     			{
    -				AttrNumber	attnum = k + FirstLowInvalidHeapAttributeNumber;
    +				AttrNumber	attphysnum = k + FirstLowInvalidHeapAttributeNumber;
     
    -				if (attnum <= 0)
    +				if (attphysnum <= 0)
     					ereport(ERROR,
     							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     							 errmsg("statistics creation on system columns is not supported")));
    diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
    index 2de0ebacec..ff9a9fc911 100644
    --- a/src/backend/commands/tablecmds.c
    +++ b/src/backend/commands/tablecmds.c
    @@ -219,7 +219,7 @@ typedef struct NewConstraint
      */
     typedef struct NewColumnValue
     {
    -	AttrNumber	attnum;			/* which column */
    +	AttrNumber	attphysnum;			/* which column */
     	Expr	   *expr;			/* expression to compute */
     	ExprState  *exprstate;		/* execution state */
     	bool		is_generated;	/* is it a GENERATED expression? */
    @@ -427,8 +427,8 @@ static ObjectAddress ATExecAddColumn(List **wqueue, AlteredTableInfo *tab,
     									 AlterTableUtilityContext *context);
     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 add_column_datatype_dependency(Oid relid, int32 attphysnum, Oid typid);
    +static void add_column_collation_dependency(Oid relid, int32 attphysnum, Oid collid);
     static void ATPrepDropNotNull(Relation rel, bool recurse, bool recursing);
     static ObjectAddress ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode);
     static void ATPrepSetNotNull(List **wqueue, Relation rel,
    @@ -444,7 +444,7 @@ static bool ConstraintImpliedByRelConstraint(Relation scanrel,
     											 List *testConstraint, List *provenConstraint);
     static ObjectAddress ATExecColumnDefault(Relation rel, const char *colName,
     										 Node *newDefault, LOCKMODE lockmode);
    -static ObjectAddress ATExecCookedColumnDefault(Relation rel, AttrNumber attnum,
    +static ObjectAddress ATExecCookedColumnDefault(Relation rel, AttrNumber attphysnum,
     											   Node *newDefault);
     static ObjectAddress ATExecAddIdentity(Relation rel, const char *colName,
     									   Node *def, LOCKMODE lockmode);
    @@ -670,7 +670,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
     	List	   *cookedDefaults;
     	Datum		reloptions;
     	ListCell   *listptr;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	bool		partitioned;
     	static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
     	Oid			ofTypeId;
    @@ -880,15 +880,15 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
     	 */
     	rawDefaults = NIL;
     	cookedDefaults = NIL;
    -	attnum = 0;
    +	attphysnum = 0;
     
     	foreach(listptr, stmt->tableElts)
     	{
     		ColumnDef  *colDef = lfirst(listptr);
     		Form_pg_attribute attr;
     
    -		attnum++;
    -		attr = TupleDescAttr(descriptor, attnum - 1);
    +		attphysnum++;
    +		attr = TupleDescAttr(descriptor, attphysnum - 1);
     
     		if (colDef->raw_default != NULL)
     		{
    @@ -897,7 +897,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
     			Assert(colDef->cooked_default == NULL);
     
     			rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
    -			rawEnt->attnum = attnum;
    +			rawEnt->attphysnum = attphysnum;
     			rawEnt->raw_default = colDef->raw_default;
     			rawEnt->missingMode = false;
     			rawEnt->generated = colDef->generated;
    @@ -912,7 +912,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
     			cooked->contype = CONSTR_DEFAULT;
     			cooked->conoid = InvalidOid;	/* until created */
     			cooked->name = NULL;
    -			cooked->attnum = attnum;
    +			cooked->attphysnum = attphysnum;
     			cooked->expr = colDef->cooked_default;
     			cooked->skip_validation = false;
     			cooked->is_local = true;	/* not used for defaults */
    @@ -2774,7 +2774,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
     					cooked->contype = CONSTR_CHECK;
     					cooked->conoid = InvalidOid;	/* until created */
     					cooked->name = pstrdup(name);
    -					cooked->attnum = 0; /* not used for constraints */
    +					cooked->attphysnum = 0; /* not used for constraints */
     					cooked->expr = expr;
     					cooked->skip_validation = false;
     					cooked->is_local = false;
    @@ -3432,7 +3432,7 @@ renameatt_internal(Oid myrelid,
     	Relation	attrelation;
     	HeapTuple	atttup;
     	Form_pg_attribute attform;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     
     	/*
     	 * Grab an exclusive lock on the target table, which we will NOT release
    @@ -3520,8 +3520,8 @@ renameatt_internal(Oid myrelid,
     						oldattname)));
     	attform = (Form_pg_attribute) GETSTRUCT(atttup);
     
    -	attnum = attform->attnum;
    -	if (attnum <= 0)
    +	attphysnum = attform->attphysnum;
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot rename system column \"%s\"",
    @@ -3550,7 +3550,7 @@ renameatt_internal(Oid myrelid,
     
     	CatalogTupleUpdate(attrelation, &atttup->t_self, atttup);
     
    -	InvokeObjectPostAlterHook(RelationRelationId, myrelid, attnum);
    +	InvokeObjectPostAlterHook(RelationRelationId, myrelid, attphysnum);
     
     	heap_freetuple(atttup);
     
    @@ -3558,7 +3558,7 @@ renameatt_internal(Oid myrelid,
     
     	relation_close(targetrelation, NoLock); /* close rel but keep lock */
     
    -	return attnum;
    +	return attphysnum;
     }
     
     /*
    @@ -3588,7 +3588,7 @@ ObjectAddress
     renameatt(RenameStmt *stmt)
     {
     	Oid			relid;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	ObjectAddress address;
     
     	/* lock level taken here should match renameatt_internal */
    @@ -3605,7 +3605,7 @@ renameatt(RenameStmt *stmt)
     		return InvalidObjectAddress;
     	}
     
    -	attnum =
    +	attphysnum =
     		renameatt_internal(relid,
     						   stmt->subname,	/* old att name */
     						   stmt->newname,	/* new att name */
    @@ -3614,7 +3614,7 @@ renameatt(RenameStmt *stmt)
     						   0,	/* expected inhcount */
     						   stmt->behavior);
     
    -	ObjectAddressSubSet(address, RelationRelationId, relid, attnum);
    +	ObjectAddressSubSet(address, RelationRelationId, relid, attphysnum);
     
     	return address;
     }
    @@ -5899,10 +5899,10 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
     					if (ex->is_generated)
     						continue;
     
    -					newslot->tts_values[ex->attnum - 1]
    +					newslot->tts_values[ex->attphysnum - 1]
     						= ExecEvalExpr(ex->exprstate,
     									   econtext,
    -									   &newslot->tts_isnull[ex->attnum - 1]);
    +									   &newslot->tts_isnull[ex->attphysnum - 1]);
     				}
     
     				ExecStoreVirtualTuple(newslot);
    @@ -5921,10 +5921,10 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
     					if (!ex->is_generated)
     						continue;
     
    -					newslot->tts_values[ex->attnum - 1]
    +					newslot->tts_values[ex->attphysnum - 1]
     						= ExecEvalExpr(ex->exprstate,
     									   econtext,
    -									   &newslot->tts_isnull[ex->attnum - 1]);
    +									   &newslot->tts_isnull[ex->attphysnum - 1]);
     				}
     
     				insertslot = newslot;
    @@ -6814,7 +6814,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
     	attribute.atttypid = typeOid;
     	attribute.attstattarget = (newattnum > 0) ? -1 : 0;
     	attribute.attlen = tform->typlen;
    -	attribute.attnum = newattnum;
    +	attribute.attphysnum = newattnum;
     	attribute.attndims = list_length(colDef->typeName->arrayBounds);
     	attribute.atttypmod = typmod;
     	attribute.attbyval = tform->typbyval;
    @@ -6865,7 +6865,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
     		RawColumnDefault *rawEnt;
     
     		rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
    -		rawEnt->attnum = attribute.attnum;
    +		rawEnt->attphysnum = attribute.attphysnum;
     		rawEnt->raw_default = copyObject(colDef->raw_default);
     
     		/*
    @@ -6900,7 +6900,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
     	 *
     	 * If there is no default, Phase 3 doesn't have to do anything, because
     	 * that effectively means that the default is NULL.  The heap tuple access
    -	 * routines always check for attnum > # of attributes in tuple, and return
    +	 * routines always check for attphysnum > # of attributes in tuple, and return
     	 * NULL if so, so without any modification of the tuple data we will get
     	 * the effect of NULL values in the new column.
     	 *
    @@ -6928,7 +6928,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
     	 * is certainly not going to touch them.  System attributes don't have
     	 * interesting defaults, either.
     	 */
    -	if (RELKIND_HAS_STORAGE(relkind) && attribute.attnum > 0)
    +	if (RELKIND_HAS_STORAGE(relkind) && attribute.attphysnum > 0)
     	{
     		/*
     		 * For an identity column, we can't use build_column_default(),
    @@ -6947,7 +6947,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
     			tab->rewrite |= AT_REWRITE_DEFAULT_VAL;
     		}
     		else
    -			defval = (Expr *) build_column_default(rel, attribute.attnum);
    +			defval = (Expr *) build_column_default(rel, attribute.attphysnum);
     
     		if (!defval && DomainHasConstraints(typeOid))
     		{
    @@ -6976,7 +6976,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
     			NewColumnValue *newval;
     
     			newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
    -			newval->attnum = attribute.attnum;
    +			newval->attphysnum = attribute.attphysnum;
     			newval->expr = expression_planner(defval);
     			newval->is_generated = (colDef->generated != '\0');
     
    @@ -6986,7 +6986,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
     		if (DomainHasConstraints(typeOid))
     			tab->rewrite |= AT_REWRITE_DEFAULT_VAL;
     
    -		if (!TupleDescAttr(rel->rd_att, attribute.attnum - 1)->atthasmissing)
    +		if (!TupleDescAttr(rel->rd_att, attribute.attphysnum - 1)->atthasmissing)
     		{
     			/*
     			 * If the new column is NOT NULL, and there is no missing value,
    @@ -7064,7 +7064,7 @@ check_for_column_name_collision(Relation rel, const char *colname,
     								bool if_not_exists)
     {
     	HeapTuple	attTuple;
    -	int			attnum;
    +	int			attphysnum;
     
     	/*
     	 * this test is deliberately not attisdropped-aware, since if one tries to
    @@ -7076,7 +7076,7 @@ check_for_column_name_collision(Relation rel, const char *colname,
     	if (!HeapTupleIsValid(attTuple))
     		return true;
     
    -	attnum = ((Form_pg_attribute) GETSTRUCT(attTuple))->attnum;
    +	attphysnum = ((Form_pg_attribute) GETSTRUCT(attTuple))->attphysnum;
     	ReleaseSysCache(attTuple);
     
     	/*
    @@ -7084,7 +7084,7 @@ check_for_column_name_collision(Relation rel, const char *colname,
     	 * names, since they are normally not shown and the user might otherwise
     	 * be confused about the reason for the conflict.
     	 */
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_DUPLICATE_COLUMN),
     				 errmsg("column name \"%s\" conflicts with a system column name",
    @@ -7113,14 +7113,14 @@ check_for_column_name_collision(Relation rel, const char *colname,
      * Install a column's dependency on its datatype.
      */
     static void
    -add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid)
    +add_column_datatype_dependency(Oid relid, int32 attphysnum, Oid typid)
     {
     	ObjectAddress myself,
     				referenced;
     
     	myself.classId = RelationRelationId;
     	myself.objectId = relid;
    -	myself.objectSubId = attnum;
    +	myself.objectSubId = attphysnum;
     	referenced.classId = TypeRelationId;
     	referenced.objectId = typid;
     	referenced.objectSubId = 0;
    @@ -7131,7 +7131,7 @@ add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid)
      * Install a column's dependency on its collation.
      */
     static void
    -add_column_collation_dependency(Oid relid, int32 attnum, Oid collid)
    +add_column_collation_dependency(Oid relid, int32 attphysnum, Oid collid)
     {
     	ObjectAddress myself,
     				referenced;
    @@ -7141,7 +7141,7 @@ add_column_collation_dependency(Oid relid, int32 attnum, Oid collid)
     	{
     		myself.classId = RelationRelationId;
     		myself.objectId = relid;
    -		myself.objectSubId = attnum;
    +		myself.objectSubId = attphysnum;
     		referenced.classId = CollationRelationId;
     		referenced.objectId = collid;
     		referenced.objectSubId = 0;
    @@ -7182,7 +7182,7 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode)
     {
     	HeapTuple	tuple;
     	Form_pg_attribute attTup;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	Relation	attr_rel;
     	List	   *indexoidlist;
     	ListCell   *indexoidscan;
    @@ -7200,10 +7200,10 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode)
     				 errmsg("column \"%s\" of relation \"%s\" does not exist",
     						colName, RelationGetRelationName(rel))));
     	attTup = (Form_pg_attribute) GETSTRUCT(tuple);
    -	attnum = attTup->attnum;
    +	attphysnum = attTup->attphysnum;
     
     	/* Prevent them from altering a system attribute */
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"",
    @@ -7250,7 +7250,7 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode)
     			 */
     			for (i = 0; i < indexStruct->indnkeyatts; i++)
     			{
    -				if (indexStruct->indkey.values[i] == attnum)
    +				if (indexStruct->indkey.values[i] == attphysnum)
     				{
     					if (indexStruct->indisprimary)
     						ereport(ERROR,
    @@ -7279,7 +7279,7 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode)
     		TupleDesc	tupDesc = RelationGetDescr(parent);
     		AttrNumber	parent_attnum;
     
    -		parent_attnum = get_attnum(parentId, colName);
    +		parent_attnum = get_attphysnum(parentId, colName);
     		if (TupleDescAttr(tupDesc, parent_attnum - 1)->attnotnull)
     			ereport(ERROR,
     					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
    @@ -7298,13 +7298,13 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode)
     		CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
     
     		ObjectAddressSubSet(address, RelationRelationId,
    -							RelationGetRelid(rel), attnum);
    +							RelationGetRelid(rel), attphysnum);
     	}
     	else
     		address = InvalidObjectAddress;
     
     	InvokeObjectPostAlterHook(RelationRelationId,
    -							  RelationGetRelid(rel), attnum);
    +							  RelationGetRelid(rel), attphysnum);
     
     	table_close(attr_rel, RowExclusiveLock);
     
    @@ -7389,7 +7389,7 @@ ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
     				 const char *colName, LOCKMODE lockmode)
     {
     	HeapTuple	tuple;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	Relation	attr_rel;
     	ObjectAddress address;
     
    @@ -7406,10 +7406,10 @@ ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
     				 errmsg("column \"%s\" of relation \"%s\" does not exist",
     						colName, RelationGetRelationName(rel))));
     
    -	attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
    +	attphysnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attphysnum;
     
     	/* Prevent them from altering a system attribute */
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"",
    @@ -7438,13 +7438,13 @@ ATExecSetNotNull(AlteredTableInfo *tab, Relation rel,
     		}
     
     		ObjectAddressSubSet(address, RelationRelationId,
    -							RelationGetRelid(rel), attnum);
    +							RelationGetRelid(rel), attphysnum);
     	}
     	else
     		address = InvalidObjectAddress;
     
     	InvokeObjectPostAlterHook(RelationRelationId,
    -							  RelationGetRelid(rel), attnum);
    +							  RelationGetRelid(rel), attphysnum);
     
     	table_close(attr_rel, RowExclusiveLock);
     
    @@ -7501,7 +7501,7 @@ NotNullImpliedByRelConstraints(Relation rel, Form_pg_attribute attr)
     	NullTest   *nnulltest = makeNode(NullTest);
     
     	nnulltest->arg = (Expr *) makeVar(1,
    -									  attr->attnum,
    +									  attr->attphysnum,
     									  attr->atttypid,
     									  attr->atttypmod,
     									  attr->attcollation,
    @@ -7537,39 +7537,39 @@ ATExecColumnDefault(Relation rel, const char *colName,
     					Node *newDefault, LOCKMODE lockmode)
     {
     	TupleDesc	tupdesc = RelationGetDescr(rel);
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	ObjectAddress address;
     
     	/*
     	 * get the number of the attribute
     	 */
    -	attnum = get_attnum(RelationGetRelid(rel), colName);
    -	if (attnum == InvalidAttrNumber)
    +	attphysnum = get_attphysnum(RelationGetRelid(rel), colName);
    +	if (attphysnum == InvalidAttrNumber)
     		ereport(ERROR,
     				(errcode(ERRCODE_UNDEFINED_COLUMN),
     				 errmsg("column \"%s\" of relation \"%s\" does not exist",
     						colName, RelationGetRelationName(rel))));
     
     	/* Prevent them from altering a system attribute */
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"",
     						colName)));
     
    -	if (TupleDescAttr(tupdesc, attnum - 1)->attidentity)
    +	if (TupleDescAttr(tupdesc, attphysnum - 1)->attidentity)
     		ereport(ERROR,
     				(errcode(ERRCODE_SYNTAX_ERROR),
     				 errmsg("column \"%s\" of relation \"%s\" is an identity column",
     						colName, RelationGetRelationName(rel)),
     				 newDefault ? 0 : errhint("Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead.")));
     
    -	if (TupleDescAttr(tupdesc, attnum - 1)->attgenerated)
    +	if (TupleDescAttr(tupdesc, attphysnum - 1)->attgenerated)
     		ereport(ERROR,
     				(errcode(ERRCODE_SYNTAX_ERROR),
     				 errmsg("column \"%s\" of relation \"%s\" is a generated column",
     						colName, RelationGetRelationName(rel)),
    -				 newDefault || TupleDescAttr(tupdesc, attnum - 1)->attgenerated != ATTRIBUTE_GENERATED_STORED ? 0 :
    +				 newDefault || TupleDescAttr(tupdesc, attphysnum - 1)->attgenerated != ATTRIBUTE_GENERATED_STORED ? 0 :
     				 errhint("Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION instead.")));
     
     	/*
    @@ -7581,7 +7581,7 @@ ATExecColumnDefault(Relation rel, const char *colName,
     	 * is preparatory to adding a new default, but as a user-initiated
     	 * operation when the user asked for a drop.
     	 */
    -	RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false,
    +	RemoveAttrDefault(RelationGetRelid(rel), attphysnum, DROP_RESTRICT, false,
     					  newDefault != NULL);
     
     	if (newDefault)
    @@ -7590,7 +7590,7 @@ ATExecColumnDefault(Relation rel, const char *colName,
     		RawColumnDefault *rawEnt;
     
     		rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
    -		rawEnt->attnum = attnum;
    +		rawEnt->attphysnum = attphysnum;
     		rawEnt->raw_default = newDefault;
     		rawEnt->missingMode = false;
     		rawEnt->generated = '\0';
    @@ -7604,7 +7604,7 @@ ATExecColumnDefault(Relation rel, const char *colName,
     	}
     
     	ObjectAddressSubSet(address, RelationRelationId,
    -						RelationGetRelid(rel), attnum);
    +						RelationGetRelid(rel), attphysnum);
     	return address;
     }
     
    @@ -7614,7 +7614,7 @@ ATExecColumnDefault(Relation rel, const char *colName,
      * Return the address of the affected column.
      */
     static ObjectAddress
    -ATExecCookedColumnDefault(Relation rel, AttrNumber attnum,
    +ATExecCookedColumnDefault(Relation rel, AttrNumber attphysnum,
     						  Node *newDefault)
     {
     	ObjectAddress address;
    @@ -7627,13 +7627,13 @@ ATExecCookedColumnDefault(Relation rel, AttrNumber attnum,
     	 * default.  (In ordinary cases, there could not be a default in place
     	 * anyway, but it's possible when combining LIKE with inheritance.)
     	 */
    -	RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false,
    +	RemoveAttrDefault(RelationGetRelid(rel), attphysnum, DROP_RESTRICT, false,
     					  true);
     
    -	(void) StoreAttrDefault(rel, attnum, newDefault, true, false);
    +	(void) StoreAttrDefault(rel, attphysnum, newDefault, true, false);
     
     	ObjectAddressSubSet(address, RelationRelationId,
    -						RelationGetRelid(rel), attnum);
    +						RelationGetRelid(rel), attphysnum);
     	return address;
     }
     
    @@ -7649,7 +7649,7 @@ ATExecAddIdentity(Relation rel, const char *colName,
     	Relation	attrelation;
     	HeapTuple	tuple;
     	Form_pg_attribute attTup;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	ObjectAddress address;
     	ColumnDef  *cdef = castNode(ColumnDef, def);
     
    @@ -7662,10 +7662,10 @@ ATExecAddIdentity(Relation rel, const char *colName,
     				 errmsg("column \"%s\" of relation \"%s\" does not exist",
     						colName, RelationGetRelationName(rel))));
     	attTup = (Form_pg_attribute) GETSTRUCT(tuple);
    -	attnum = attTup->attnum;
    +	attphysnum = attTup->attphysnum;
     
     	/* Can't alter a system attribute */
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"",
    @@ -7699,9 +7699,9 @@ ATExecAddIdentity(Relation rel, const char *colName,
     
     	InvokeObjectPostAlterHook(RelationRelationId,
     							  RelationGetRelid(rel),
    -							  attTup->attnum);
    +							  attTup->attphysnum);
     	ObjectAddressSubSet(address, RelationRelationId,
    -						RelationGetRelid(rel), attnum);
    +						RelationGetRelid(rel), attphysnum);
     	heap_freetuple(tuple);
     
     	table_close(attrelation, RowExclusiveLock);
    @@ -7721,7 +7721,7 @@ ATExecSetIdentity(Relation rel, const char *colName, Node *def, LOCKMODE lockmod
     	DefElem    *generatedEl = NULL;
     	HeapTuple	tuple;
     	Form_pg_attribute attTup;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	Relation	attrelation;
     	ObjectAddress address;
     
    @@ -7757,9 +7757,9 @@ ATExecSetIdentity(Relation rel, const char *colName, Node *def, LOCKMODE lockmod
     						colName, RelationGetRelationName(rel))));
     
     	attTup = (Form_pg_attribute) GETSTRUCT(tuple);
    -	attnum = attTup->attnum;
    +	attphysnum = attTup->attphysnum;
     
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"",
    @@ -7778,9 +7778,9 @@ ATExecSetIdentity(Relation rel, const char *colName, Node *def, LOCKMODE lockmod
     
     		InvokeObjectPostAlterHook(RelationRelationId,
     								  RelationGetRelid(rel),
    -								  attTup->attnum);
    +								  attTup->attphysnum);
     		ObjectAddressSubSet(address, RelationRelationId,
    -							RelationGetRelid(rel), attnum);
    +							RelationGetRelid(rel), attphysnum);
     	}
     	else
     		address = InvalidObjectAddress;
    @@ -7801,7 +7801,7 @@ ATExecDropIdentity(Relation rel, const char *colName, bool missing_ok, LOCKMODE
     {
     	HeapTuple	tuple;
     	Form_pg_attribute attTup;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	Relation	attrelation;
     	ObjectAddress address;
     	Oid			seqid;
    @@ -7816,9 +7816,9 @@ ATExecDropIdentity(Relation rel, const char *colName, bool missing_ok, LOCKMODE
     						colName, RelationGetRelationName(rel))));
     
     	attTup = (Form_pg_attribute) GETSTRUCT(tuple);
    -	attnum = attTup->attnum;
    +	attphysnum = attTup->attphysnum;
     
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"",
    @@ -7847,15 +7847,15 @@ ATExecDropIdentity(Relation rel, const char *colName, bool missing_ok, LOCKMODE
     
     	InvokeObjectPostAlterHook(RelationRelationId,
     							  RelationGetRelid(rel),
    -							  attTup->attnum);
    +							  attTup->attphysnum);
     	ObjectAddressSubSet(address, RelationRelationId,
    -						RelationGetRelid(rel), attnum);
    +						RelationGetRelid(rel), attphysnum);
     	heap_freetuple(tuple);
     
     	table_close(attrelation, RowExclusiveLock);
     
     	/* drop the internal sequence */
    -	seqid = getIdentitySequence(RelationGetRelid(rel), attnum, false);
    +	seqid = getIdentitySequence(RelationGetRelid(rel), attphysnum, false);
     	deleteDependencyRecordsForClass(RelationRelationId, seqid,
     									RelationRelationId, DEPENDENCY_INTERNAL);
     	CommandCounterIncrement();
    @@ -7921,7 +7921,7 @@ ATExecDropExpression(Relation rel, const char *colName, bool missing_ok, LOCKMOD
     {
     	HeapTuple	tuple;
     	Form_pg_attribute attTup;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	Relation	attrelation;
     	Oid			attrdefoid;
     	ObjectAddress address;
    @@ -7935,9 +7935,9 @@ ATExecDropExpression(Relation rel, const char *colName, bool missing_ok, LOCKMOD
     						colName, RelationGetRelationName(rel))));
     
     	attTup = (Form_pg_attribute) GETSTRUCT(tuple);
    -	attnum = attTup->attnum;
    +	attphysnum = attTup->attphysnum;
     
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"",
    @@ -7970,7 +7970,7 @@ ATExecDropExpression(Relation rel, const char *colName, bool missing_ok, LOCKMOD
     
     	InvokeObjectPostAlterHook(RelationRelationId,
     							  RelationGetRelid(rel),
    -							  attnum);
    +							  attphysnum);
     	heap_freetuple(tuple);
     
     	table_close(attrelation, RowExclusiveLock);
    @@ -7980,10 +7980,10 @@ ATExecDropExpression(Relation rel, const char *colName, bool missing_ok, LOCKMOD
     	 * its INTERNAL dependency on the column, which would otherwise cause
     	 * dependency.c to refuse to perform the deletion.
     	 */
    -	attrdefoid = GetAttrDefaultOid(RelationGetRelid(rel), attnum);
    +	attrdefoid = GetAttrDefaultOid(RelationGetRelid(rel), attphysnum);
     	if (!OidIsValid(attrdefoid))
    -		elog(ERROR, "could not find attrdef tuple for relation %u attnum %d",
    -			 RelationGetRelid(rel), attnum);
    +		elog(ERROR, "could not find attrdef tuple for relation %u attphysnum %d",
    +			 RelationGetRelid(rel), attphysnum);
     	(void) deleteDependencyRecordsFor(AttrDefaultRelationId, attrdefoid, false);
     
     	/* Make above changes visible */
    @@ -7994,11 +7994,11 @@ ATExecDropExpression(Relation rel, const char *colName, bool missing_ok, LOCKMOD
     	 * safety, but at present we do not expect anything to depend on the
     	 * default.
     	 */
    -	RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT,
    +	RemoveAttrDefault(RelationGetRelid(rel), attphysnum, DROP_RESTRICT,
     					  false, false);
     
     	ObjectAddressSubSet(address, RelationRelationId,
    -						RelationGetRelid(rel), attnum);
    +						RelationGetRelid(rel), attphysnum);
     	return address;
     }
     
    @@ -8014,7 +8014,7 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa
     	Relation	attrelation;
     	HeapTuple	tuple;
     	Form_pg_attribute attrtuple;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	ObjectAddress address;
     
     	/*
    @@ -8075,8 +8075,8 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa
     
     	attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
     
    -	attnum = attrtuple->attnum;
    -	if (attnum <= 0)
    +	attphysnum = attrtuple->attphysnum;
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"",
    @@ -8085,12 +8085,12 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa
     	if (rel->rd_rel->relkind == RELKIND_INDEX ||
     		rel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
     	{
    -		if (attnum > rel->rd_index->indnkeyatts)
    +		if (attphysnum > rel->rd_index->indnkeyatts)
     			ereport(ERROR,
     					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     					 errmsg("cannot alter statistics on included column \"%s\" of index \"%s\"",
     							NameStr(attrtuple->attname), RelationGetRelationName(rel))));
    -		else if (rel->rd_index->indkey.values[attnum - 1] != 0)
    +		else if (rel->rd_index->indkey.values[attphysnum - 1] != 0)
     			ereport(ERROR,
     					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     					 errmsg("cannot alter statistics on non-expression column \"%s\" of index \"%s\"",
    @@ -8104,9 +8104,9 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa
     
     	InvokeObjectPostAlterHook(RelationRelationId,
     							  RelationGetRelid(rel),
    -							  attrtuple->attnum);
    +							  attrtuple->attphysnum);
     	ObjectAddressSubSet(address, RelationRelationId,
    -						RelationGetRelid(rel), attnum);
    +						RelationGetRelid(rel), attphysnum);
     	heap_freetuple(tuple);
     
     	table_close(attrelation, RowExclusiveLock);
    @@ -8125,7 +8125,7 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options,
     	HeapTuple	tuple,
     				newtuple;
     	Form_pg_attribute attrtuple;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	Datum		datum,
     				newOptions;
     	bool		isnull;
    @@ -8145,8 +8145,8 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options,
     						colName, RelationGetRelationName(rel))));
     	attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
     
    -	attnum = attrtuple->attnum;
    -	if (attnum <= 0)
    +	attphysnum = attrtuple->attphysnum;
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"",
    @@ -8177,9 +8177,9 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options,
     
     	InvokeObjectPostAlterHook(RelationRelationId,
     							  RelationGetRelid(rel),
    -							  attrtuple->attnum);
    +							  attrtuple->attphysnum);
     	ObjectAddressSubSet(address, RelationRelationId,
    -						RelationGetRelid(rel), attnum);
    +						RelationGetRelid(rel), attphysnum);
     
     	heap_freetuple(newtuple);
     
    @@ -8198,7 +8198,7 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options,
      */
     static void
     SetIndexStorageProperties(Relation rel, Relation attrelation,
    -						  AttrNumber attnum,
    +						  AttrNumber attphysnum,
     						  bool setstorage, char newstorage,
     						  bool setcompression, char newcompression,
     						  LOCKMODE lockmode)
    @@ -8216,7 +8216,7 @@ SetIndexStorageProperties(Relation rel, Relation attrelation,
     
     		for (int i = 0; i < indrel->rd_index->indnatts; i++)
     		{
    -			if (indrel->rd_index->indkey.values[i] == attnum)
    +			if (indrel->rd_index->indkey.values[i] == attphysnum)
     			{
     				indattnum = i + 1;
     				break;
    @@ -8245,7 +8245,7 @@ SetIndexStorageProperties(Relation rel, Relation attrelation,
     
     			InvokeObjectPostAlterHook(RelationRelationId,
     									  RelationGetRelid(rel),
    -									  attrtuple->attnum);
    +									  attrtuple->attphysnum);
     
     			heap_freetuple(tuple);
     		}
    @@ -8267,7 +8267,7 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
     	Relation	attrelation;
     	HeapTuple	tuple;
     	Form_pg_attribute attrtuple;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	ObjectAddress address;
     
     	Assert(IsA(newValue, String));
    @@ -8301,8 +8301,8 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
     						colName, RelationGetRelationName(rel))));
     	attrtuple = (Form_pg_attribute) GETSTRUCT(tuple);
     
    -	attnum = attrtuple->attnum;
    -	if (attnum <= 0)
    +	attphysnum = attrtuple->attphysnum;
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"",
    @@ -8324,7 +8324,7 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
     
     	InvokeObjectPostAlterHook(RelationRelationId,
     							  RelationGetRelid(rel),
    -							  attrtuple->attnum);
    +							  attrtuple->attphysnum);
     
     	heap_freetuple(tuple);
     
    @@ -8332,7 +8332,7 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
     	 * Apply the change to indexes as well (only for simple index columns,
     	 * matching behavior of index.c ConstructTupleDescriptor()).
     	 */
    -	SetIndexStorageProperties(rel, attrelation, attnum,
    +	SetIndexStorageProperties(rel, attrelation, attphysnum,
     							  true, newstorage,
     							  false, 0,
     							  lockmode);
    @@ -8340,7 +8340,7 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc
     	table_close(attrelation, RowExclusiveLock);
     
     	ObjectAddressSubSet(address, RelationRelationId,
    -						RelationGetRelid(rel), attnum);
    +						RelationGetRelid(rel), attphysnum);
     	return address;
     }
     
    @@ -8391,7 +8391,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
     {
     	HeapTuple	tuple;
     	Form_pg_attribute targetatt;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	List	   *children;
     	ObjectAddress object;
     	bool		is_expr;
    @@ -8428,10 +8428,10 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
     	}
     	targetatt = (Form_pg_attribute) GETSTRUCT(tuple);
     
    -	attnum = targetatt->attnum;
    +	attphysnum = targetatt->attphysnum;
     
     	/* Can't drop a system attribute */
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot drop system column \"%s\"",
    @@ -8453,7 +8453,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
     	 * of the whole table, which is surely not what the user expected.)
     	 */
     	if (has_partition_attrs(rel,
    -							bms_make_singleton(attnum - FirstLowInvalidHeapAttributeNumber),
    +							bms_make_singleton(attphysnum - FirstLowInvalidHeapAttributeNumber),
     							&is_expr))
     		ereport(ERROR,
     				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
    @@ -8557,7 +8557,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
     	/* Add object to delete */
     	object.classId = RelationRelationId;
     	object.objectId = RelationGetRelid(rel);
    -	object.objectSubId = attnum;
    +	object.objectSubId = attphysnum;
     	add_exact_object_address(&object, addrs);
     
     	if (!recursing)
    @@ -9490,11 +9490,11 @@ validateFkOnDeleteSetColumns(int numfks, const int16 *fkattnums,
      * parentConstr is the OID of a parent constraint; InvalidOid if this is a
      * top-level constraint.
      * numfks is the number of columns in the foreign key
    - * pkattnum is the attnum array of referenced attributes.
    - * fkattnum is the attnum array of referencing attributes.
    + * pkattnum is the attphysnum array of referenced attributes.
    + * fkattnum is the attphysnum array of referencing attributes.
      * numfkdelsetcols is the number of columns in the ON DELETE SET NULL/DELETE
      *      (...) clause
    - * fkdelsetcols is the attnum array of the columns in the ON DELETE SET
    + * fkdelsetcols is the attphysnum array of the columns in the ON DELETE SET
      *      NULL/DELETE clause
      * pf/pp/ffeqoperators are OID array of operators between columns.
      * old_check_ok signals that this constraint replaces an existing one that
    @@ -9708,12 +9708,12 @@ addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint, Relation rel,
      * indexOid is the OID of the index (on pkrel) implementing this constraint.
      * parentConstr is the OID of the parent constraint (there is always one).
      * numfks is the number of columns in the foreign key
    - * pkattnum is the attnum array of referenced attributes.
    - * fkattnum is the attnum array of referencing attributes.
    + * pkattnum is the attphysnum array of referenced attributes.
    + * fkattnum is the attphysnum array of referencing attributes.
      * pf/pp/ffeqoperators are OID array of operators between columns.
      * numfkdelsetcols is the number of columns in the ON DELETE SET NULL/DELETE
      *      (...) clause
    - * fkdelsetcols is the attnum array of the columns in the ON DELETE SET
    + * fkdelsetcols is the attphysnum array of the columns in the ON DELETE SET
      *      NULL/DELETE clause
      * old_check_ok signals that this constraint replaces an existing one that
      *		was already validated (thus this one doesn't need validation).
    @@ -11144,16 +11144,16 @@ ATExecValidateConstraint(List **wqueue, Relation rel, char *constrName,
     /*
      * transformColumnNameList - transform list of column names
      *
    - * Lookup each name and return its attnum and, optionally, type OID
    + * Lookup each name and return its attphysnum and, optionally, type OID
      */
     static int
     transformColumnNameList(Oid relId, List *colList,
     						int16 *attnums, Oid *atttypids)
     {
     	ListCell   *l;
    -	int			attnum;
    +	int			attphysnum;
     
    -	attnum = 0;
    +	attphysnum = 0;
     	foreach(l, colList)
     	{
     		char	   *attname = strVal(lfirst(l));
    @@ -11165,19 +11165,19 @@ transformColumnNameList(Oid relId, List *colList,
     					(errcode(ERRCODE_UNDEFINED_COLUMN),
     					 errmsg("column \"%s\" referenced in foreign key constraint does not exist",
     							attname)));
    -		if (attnum >= INDEX_MAX_KEYS)
    +		if (attphysnum >= INDEX_MAX_KEYS)
     			ereport(ERROR,
     					(errcode(ERRCODE_TOO_MANY_COLUMNS),
     					 errmsg("cannot have more than %d keys in a foreign key",
     							INDEX_MAX_KEYS)));
    -		attnums[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->attnum;
    +		attnums[attphysnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->attphysnum;
     		if (atttypids != NULL)
    -			atttypids[attnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;
    +			atttypids[attphysnum] = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;
     		ReleaseSysCache(atttuple);
    -		attnum++;
    +		attphysnum++;
     	}
     
    -	return attnum;
    +	return attphysnum;
     }
     
     /*
    @@ -11360,7 +11360,7 @@ transformFkeyCheckAttrs(Relation pkrel,
     			indclass = (oidvector *) DatumGetPointer(indclassDatum);
     
     			/*
    -			 * The given attnum list may match the index columns in any order.
    +			 * The given attphysnum list may match the index columns in any order.
     			 * Check for a match, and extract the appropriate opclasses while
     			 * we're at it.
     			 *
    @@ -12070,7 +12070,7 @@ ATPrepAlterColumnType(List **wqueue,
     	Node	   *transform = def->cooked_default;
     	HeapTuple	tuple;
     	Form_pg_attribute attTup;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	Oid			targettype;
     	int32		targettypmod;
     	Oid			targetcollid;
    @@ -12092,10 +12092,10 @@ ATPrepAlterColumnType(List **wqueue,
     				 errmsg("column \"%s\" of relation \"%s\" does not exist",
     						colName, RelationGetRelationName(rel))));
     	attTup = (Form_pg_attribute) GETSTRUCT(tuple);
    -	attnum = attTup->attnum;
    +	attphysnum = attTup->attphysnum;
     
     	/* Can't alter a system attribute */
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"",
    @@ -12114,7 +12114,7 @@ ATPrepAlterColumnType(List **wqueue,
     
     	/* Don't alter columns used in the partition key */
     	if (has_partition_attrs(rel,
    -							bms_make_singleton(attnum - FirstLowInvalidHeapAttributeNumber),
    +							bms_make_singleton(attphysnum - FirstLowInvalidHeapAttributeNumber),
     							&is_expr))
     		ereport(ERROR,
     				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
    @@ -12150,7 +12150,7 @@ ATPrepAlterColumnType(List **wqueue,
     		 */
     		if (!transform)
     		{
    -			transform = (Node *) makeVar(1, attnum,
    +			transform = (Node *) makeVar(1, attphysnum,
     										 attTup->atttypid, attTup->atttypmod,
     										 attTup->attcollation,
     										 0);
    @@ -12195,12 +12195,12 @@ ATPrepAlterColumnType(List **wqueue,
     		 * contents.
     		 */
     		newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
    -		newval->attnum = attnum;
    +		newval->attphysnum = attphysnum;
     		newval->expr = (Expr *) transform;
     		newval->is_generated = false;
     
     		tab->newvals = lappend(tab->newvals, newval);
    -		if (ATColumnChangeRequiresRewrite(transform, attnum))
    +		if (ATColumnChangeRequiresRewrite(transform, attphysnum))
     			tab->rewrite |= AT_REWRITE_COLUMN_REWRITE;
     	}
     	else if (transform)
    @@ -12394,7 +12394,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
     	HeapTuple	heapTup;
     	Form_pg_attribute attTup,
     				attOldTup;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	HeapTuple	typeTuple;
     	Form_pg_type tform;
     	Oid			targettype;
    @@ -12433,8 +12433,8 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
     				 errmsg("column \"%s\" of relation \"%s\" does not exist",
     						colName, RelationGetRelationName(rel))));
     	attTup = (Form_pg_attribute) GETSTRUCT(heapTup);
    -	attnum = attTup->attnum;
    -	attOldTup = TupleDescAttr(tab->oldDesc, attnum - 1);
    +	attphysnum = attTup->attphysnum;
    +	attOldTup = TupleDescAttr(tab->oldDesc, attphysnum - 1);
     
     	/* Check for multiple ALTER TYPE on same column --- can't cope */
     	if (attTup->atttypid != attOldTup->atttypid ||
    @@ -12465,7 +12465,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
     	 */
     	if (attTup->atthasdef)
     	{
    -		defaultexpr = build_column_default(rel, attnum);
    +		defaultexpr = build_column_default(rel, attphysnum);
     		Assert(defaultexpr);
     		defaultexpr = strip_implicit_coercions(defaultexpr);
     		defaultexpr = coerce_to_target_type(NULL,	/* no UNKNOWN params */
    @@ -12513,7 +12513,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
     	ScanKeyInit(&key[2],
     				Anum_pg_depend_refobjsubid,
     				BTEqualStrategyNumber, F_INT4EQ,
    -				Int32GetDatum((int32) attnum));
    +				Int32GetDatum((int32) attphysnum));
     
     	scan = systable_beginscan(depRel, DependReferenceIndexId, true,
     							  NULL, 3, key);
    @@ -12613,7 +12613,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
     					ObjectAddress col = GetAttrDefaultColumnAddress(foundObject.objectId);
     
     					if (col.objectId == RelationGetRelid(rel) &&
    -						col.objectSubId == attnum)
    +						col.objectSubId == attphysnum)
     					{
     						/*
     						 * Ignore the column's own default expression, which
    @@ -12719,7 +12719,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
     	ScanKeyInit(&key[2],
     				Anum_pg_depend_objsubid,
     				BTEqualStrategyNumber, F_INT4EQ,
    -				Int32GetDatum((int32) attnum));
    +				Int32GetDatum((int32) attphysnum));
     
     	scan = systable_beginscan(depRel, DependDependerIndexId, true,
     							  NULL, 3, key);
    @@ -12835,16 +12835,16 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
     	table_close(attrelation, RowExclusiveLock);
     
     	/* Install dependencies on new datatype and collation */
    -	add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype);
    -	add_column_collation_dependency(RelationGetRelid(rel), attnum, targetcollid);
    +	add_column_datatype_dependency(RelationGetRelid(rel), attphysnum, targettype);
    +	add_column_collation_dependency(RelationGetRelid(rel), attphysnum, targetcollid);
     
     	/*
     	 * Drop any pg_statistic entry for the column, since it's now wrong type
     	 */
    -	RemoveStatistics(RelationGetRelid(rel), attnum);
    +	RemoveStatistics(RelationGetRelid(rel), attphysnum);
     
     	InvokeObjectPostAlterHook(RelationRelationId,
    -							  RelationGetRelid(rel), attnum);
    +							  RelationGetRelid(rel), attphysnum);
     
     	/*
     	 * Update the default, if present, by brute force --- remove and re-add
    @@ -12862,11 +12862,11 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
     		 */
     		if (attTup->attgenerated)
     		{
    -			Oid			attrdefoid = GetAttrDefaultOid(RelationGetRelid(rel), attnum);
    +			Oid			attrdefoid = GetAttrDefaultOid(RelationGetRelid(rel), attphysnum);
     
     			if (!OidIsValid(attrdefoid))
    -				elog(ERROR, "could not find attrdef tuple for relation %u attnum %d",
    -					 RelationGetRelid(rel), attnum);
    +				elog(ERROR, "could not find attrdef tuple for relation %u attphysnum %d",
    +					 RelationGetRelid(rel), attphysnum);
     			(void) deleteDependencyRecordsFor(AttrDefaultRelationId, attrdefoid, false);
     		}
     
    @@ -12880,14 +12880,14 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
     		 * We use RESTRICT here for safety, but at present we do not expect
     		 * anything to depend on the default.
     		 */
    -		RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, true,
    +		RemoveAttrDefault(RelationGetRelid(rel), attphysnum, DROP_RESTRICT, true,
     						  true);
     
    -		StoreAttrDefault(rel, attnum, defaultexpr, true, false);
    +		StoreAttrDefault(rel, attphysnum, defaultexpr, true, false);
     	}
     
     	ObjectAddressSubSet(address, RelationRelationId,
    -						RelationGetRelid(rel), attnum);
    +						RelationGetRelid(rel), attphysnum);
     
     	/* Cleanup */
     	heap_freetuple(heapTup);
    @@ -13568,7 +13568,7 @@ ATExecAlterColumnGenericOptions(Relation rel,
     	Datum		datum;
     	Form_pg_foreign_table fttableform;
     	Form_pg_attribute atttableform;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	ObjectAddress address;
     
     	if (options == NIL)
    @@ -13599,8 +13599,8 @@ ATExecAlterColumnGenericOptions(Relation rel,
     
     	/* Prevent them from altering a system attribute */
     	atttableform = (Form_pg_attribute) GETSTRUCT(tuple);
    -	attnum = atttableform->attnum;
    -	if (attnum <= 0)
    +	attphysnum = atttableform->attphysnum;
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"", colName)));
    @@ -13641,9 +13641,9 @@ ATExecAlterColumnGenericOptions(Relation rel,
     
     	InvokeObjectPostAlterHook(RelationRelationId,
     							  RelationGetRelid(rel),
    -							  atttableform->attnum);
    +							  atttableform->attphysnum);
     	ObjectAddressSubSet(address, RelationRelationId,
    -						RelationGetRelid(rel), attnum);
    +						RelationGetRelid(rel), attphysnum);
     
     	ReleaseSysCache(tuple);
     
    @@ -13918,7 +13918,7 @@ change_owner_fix_column_acls(Oid relationOid, Oid oldOwnerId, Oid newOwnerId)
     				Anum_pg_attribute_attrelid,
     				BTEqualStrategyNumber, F_OIDEQ,
     				ObjectIdGetDatum(relationOid));
    -	scan = systable_beginscan(attRelation, AttributeRelidNumIndexId,
    +	scan = systable_beginscan(attRelation, AttributeRelidPhysNumIndexId,
     							  true, NULL, 1, key);
     	while (HeapTupleIsValid(attributeTuple = systable_getnext(scan)))
     	{
    @@ -15062,7 +15062,7 @@ MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel)
     
     				for (int i = 0; i < child_constr->num_defval; i++)
     				{
    -					if (child_constr->defval[i].adnum == childatt->attnum)
    +					if (child_constr->defval[i].adnum == childatt->attphysnum)
     					{
     						child_expr =
     							TextDatumGetCString(DirectFunctionCall2(pg_get_expr,
    @@ -15075,7 +15075,7 @@ MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel)
     
     				for (int i = 0; i < parent_constr->num_defval; i++)
     				{
    -					if (parent_constr->defval[i].adnum == attribute->attnum)
    +					if (parent_constr->defval[i].adnum == attribute->attphysnum)
     					{
     						parent_expr =
     							TextDatumGetCString(DirectFunctionCall2(pg_get_expr,
    @@ -15441,7 +15441,7 @@ RemoveInheritance(Relation child_rel, Relation parent_rel, bool expect_detached)
     				Anum_pg_attribute_attrelid,
     				BTEqualStrategyNumber, F_OIDEQ,
     				ObjectIdGetDatum(RelationGetRelid(child_rel)));
    -	scan = systable_beginscan(catalogRelation, AttributeRelidNumIndexId,
    +	scan = systable_beginscan(catalogRelation, AttributeRelidPhysNumIndexId,
     							  true, NULL, 1, key);
     	while (HeapTupleIsValid(attributeTuple = systable_getnext(scan)))
     	{
    @@ -16165,7 +16165,7 @@ ATExecSetCompression(AlteredTableInfo *tab,
     	Relation	attrel;
     	HeapTuple	tuple;
     	Form_pg_attribute atttableform;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	char	   *compression;
     	char		cmethod;
     	ObjectAddress address;
    @@ -16185,8 +16185,8 @@ ATExecSetCompression(AlteredTableInfo *tab,
     
     	/* prevent them from altering a system attribute */
     	atttableform = (Form_pg_attribute) GETSTRUCT(tuple);
    -	attnum = atttableform->attnum;
    -	if (attnum <= 0)
    +	attphysnum = atttableform->attphysnum;
    +	if (attphysnum <= 0)
     		ereport(ERROR,
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot alter system column \"%s\"", column)));
    @@ -16203,13 +16203,13 @@ ATExecSetCompression(AlteredTableInfo *tab,
     
     	InvokeObjectPostAlterHook(RelationRelationId,
     							  RelationGetRelid(rel),
    -							  attnum);
    +							  attphysnum);
     
     	/*
     	 * Apply the change to indexes as well (only for simple index columns,
     	 * matching behavior of index.c ConstructTupleDescriptor()).
     	 */
    -	SetIndexStorageProperties(rel, attrel, attnum,
    +	SetIndexStorageProperties(rel, attrel, attphysnum,
     							  false, 0,
     							  true, cmethod,
     							  lockmode);
    @@ -16222,7 +16222,7 @@ ATExecSetCompression(AlteredTableInfo *tab,
     	CommandCounterIncrement();
     
     	ObjectAddressSubSet(address, RelationRelationId,
    -						RelationGetRelid(rel), attnum);
    +						RelationGetRelid(rel), attphysnum);
     	return address;
     }
     
    @@ -17247,7 +17247,7 @@ ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNu
     						 parser_errposition(pstate, pelem->location)));
     			attform = (Form_pg_attribute) GETSTRUCT(atttuple);
     
    -			if (attform->attnum <= 0)
    +			if (attform->attphysnum <= 0)
     				ereport(ERROR,
     						(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
     						 errmsg("cannot use system column \"%s\" in partition key",
    @@ -17266,7 +17266,7 @@ ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNu
     								   pelem->name),
     						 parser_errposition(pstate, pelem->location)));
     
    -			partattrs[attn] = attform->attnum;
    +			partattrs[attn] = attform->attphysnum;
     			atttype = attform->atttypid;
     			attcollation = attform->attcollation;
     			ReleaseSysCache(atttuple);
    diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
    index 13cb516752..b67128e9fe 100644
    --- a/src/backend/commands/trigger.c
    +++ b/src/backend/commands/trigger.c
    @@ -947,12 +947,12 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString,
     		foreach(cell, stmt->columns)
     		{
     			char	   *name = strVal(lfirst(cell));
    -			int16		attnum;
    +			int16		attphysnum;
     			int			j;
     
     			/* Lookup column name.  System columns are not allowed */
    -			attnum = attnameAttNum(rel, name, false);
    -			if (attnum == InvalidAttrNumber)
    +			attphysnum = attnameAttNum(rel, name, false);
    +			if (attphysnum == InvalidAttrNumber)
     				ereport(ERROR,
     						(errcode(ERRCODE_UNDEFINED_COLUMN),
     						 errmsg("column \"%s\" of relation \"%s\" does not exist",
    @@ -961,14 +961,14 @@ CreateTriggerFiringOn(CreateTrigStmt *stmt, const char *queryString,
     			/* Check for duplicates */
     			for (j = i - 1; j >= 0; j--)
     			{
    -				if (columns[j] == attnum)
    +				if (columns[j] == attphysnum)
     					ereport(ERROR,
     							(errcode(ERRCODE_DUPLICATE_COLUMN),
     							 errmsg("column \"%s\" specified more than once",
     									name)));
     			}
     
    -			columns[i++] = attnum;
    +			columns[i++] = attphysnum;
     		}
     	}
     	tgattr = buildint2vector(columns, ncolumns);
    diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
    index 4cc4e3c00f..0797ee67f7 100644
    --- a/src/backend/commands/tsearchcmds.c
    +++ b/src/backend/commands/tsearchcmds.c
    @@ -62,10 +62,10 @@ static DefElem *buildDefItem(const char *name, const char *val,
     /*
      * lookup a parser support function and return its OID (as a Datum)
      *
    - * attnum is the pg_ts_parser column the function will go into
    + * attphysnum is the pg_ts_parser column the function will go into
      */
     static Datum
    -get_ts_parser_func(DefElem *defel, int attnum)
    +get_ts_parser_func(DefElem *defel, int attphysnum)
     {
     	List	   *funcName = defGetQualifiedName(defel);
     	Oid			typeId[3];
    @@ -75,7 +75,7 @@ get_ts_parser_func(DefElem *defel, int attnum)
     
     	retTypeId = INTERNALOID;	/* correct for most */
     	typeId[0] = INTERNALOID;
    -	switch (attnum)
    +	switch (attphysnum)
     	{
     		case Anum_pg_ts_parser_prsstart:
     			nargs = 2;
    @@ -107,7 +107,7 @@ get_ts_parser_func(DefElem *defel, int attnum)
     		default:
     			/* should not be here */
     			elog(ERROR, "unrecognized attribute for text search parser: %d",
    -				 attnum);
    +				 attphysnum);
     			nargs = 0;			/* keep compiler quiet */
     	}
     
    @@ -597,10 +597,10 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt)
     /*
      * lookup a template support function and return its OID (as a Datum)
      *
    - * attnum is the pg_ts_template column the function will go into
    + * attphysnum is the pg_ts_template column the function will go into
      */
     static Datum
    -get_ts_template_func(DefElem *defel, int attnum)
    +get_ts_template_func(DefElem *defel, int attphysnum)
     {
     	List	   *funcName = defGetQualifiedName(defel);
     	Oid			typeId[4];
    @@ -613,7 +613,7 @@ get_ts_template_func(DefElem *defel, int attnum)
     	typeId[1] = INTERNALOID;
     	typeId[2] = INTERNALOID;
     	typeId[3] = INTERNALOID;
    -	switch (attnum)
    +	switch (attphysnum)
     	{
     		case Anum_pg_ts_template_tmplinit:
     			nargs = 1;
    @@ -624,7 +624,7 @@ get_ts_template_func(DefElem *defel, int attnum)
     		default:
     			/* should not be here */
     			elog(ERROR, "unrecognized attribute for text search template: %d",
    -				 attnum);
    +				 attphysnum);
     			nargs = 0;			/* keep compiler quiet */
     	}
     
    diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
    index 9b92b04242..e59afbe7cd 100644
    --- a/src/backend/commands/typecmds.c
    +++ b/src/backend/commands/typecmds.c
    @@ -2758,10 +2758,10 @@ AlterDomainNotNull(List *names, bool notNull)
     				/* Test attributes that are of the domain */
     				for (i = 0; i < rtc->natts; i++)
     				{
    -					int			attnum = rtc->atts[i];
    -					Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
    +					int			attphysnum = rtc->atts[i];
    +					Form_pg_attribute attr = TupleDescAttr(tupdesc, attphysnum - 1);
     
    -					if (slot_attisnull(slot, attnum))
    +					if (slot_attisnull(slot, attphysnum))
     					{
     						/*
     						 * In principle the auxiliary information for this
    @@ -2776,7 +2776,7 @@ AlterDomainNotNull(List *names, bool notNull)
     								 errmsg("column \"%s\" of table \"%s\" contains null values",
     										NameStr(attr->attname),
     										RelationGetRelationName(testrel)),
    -								 errtablecol(testrel, attnum)));
    +								 errtablecol(testrel, attphysnum)));
     					}
     				}
     			}
    @@ -3174,13 +3174,13 @@ validateDomainConstraint(Oid domainoid, char *ccbin)
     			/* Test attributes that are of the domain */
     			for (i = 0; i < rtc->natts; i++)
     			{
    -				int			attnum = rtc->atts[i];
    +				int			attphysnum = rtc->atts[i];
     				Datum		d;
     				bool		isNull;
     				Datum		conResult;
    -				Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
    +				Form_pg_attribute attr = TupleDescAttr(tupdesc, attphysnum - 1);
     
    -				d = slot_getattr(slot, attnum, &isNull);
    +				d = slot_getattr(slot, attphysnum, &isNull);
     
     				econtext->domainValue_datum = d;
     				econtext->domainValue_isNull = isNull;
    @@ -3204,7 +3204,7 @@ validateDomainConstraint(Oid domainoid, char *ccbin)
     							 errmsg("column \"%s\" of table \"%s\" contains values that violate the new constraint",
     									NameStr(attr->attname),
     									RelationGetRelationName(testrel)),
    -							 errtablecol(testrel, attnum)));
    +							 errtablecol(testrel, attphysnum)));
     				}
     			}
     
    diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
    index 2831e7978b..63e0617430 100644
    --- a/src/backend/executor/execExpr.c
    +++ b/src/backend/executor/execExpr.c
    @@ -379,7 +379,7 @@ ExecBuildProjectionInfo(List *targetList,
     	{
     		TargetEntry *tle = lfirst_node(TargetEntry, lc);
     		Var		   *variable = NULL;
    -		AttrNumber	attnum = 0;
    +		AttrNumber	attphysnum = 0;
     		bool		isSafeVar = false;
     
     		/*
    @@ -396,13 +396,13 @@ ExecBuildProjectionInfo(List *targetList,
     		{
     			/* Non-system Var, but how safe is it? */
     			variable = (Var *) tle->expr;
    -			attnum = variable->varattno;
    +			attphysnum = variable->varattno;
     
     			if (inputDesc == NULL)
     				isSafeVar = true;	/* can't check, just assume OK */
    -			else if (attnum <= inputDesc->natts)
    +			else if (attphysnum <= inputDesc->natts)
     			{
    -				Form_pg_attribute attr = TupleDescAttr(inputDesc, attnum - 1);
    +				Form_pg_attribute attr = TupleDescAttr(inputDesc, attphysnum - 1);
     
     				/*
     				 * If user attribute is dropped or has a type mismatch, don't
    @@ -439,7 +439,7 @@ ExecBuildProjectionInfo(List *targetList,
     					break;
     			}
     
    -			scratch.d.assign_var.attnum = attnum - 1;
    +			scratch.d.assign_var.attphysnum = attphysnum - 1;
     			scratch.d.assign_var.resultnum = tle->resno - 1;
     			ExprEvalPushStep(state, &scratch);
     		}
    @@ -584,15 +584,15 @@ ExecBuildUpdateProjection(List *targetList,
     	 * sufficiently deconstructed.  The scan tuple must be deconstructed at
     	 * least as far as the last old column we need.
     	 */
    -	for (int attnum = relDesc->natts; attnum > 0; attnum--)
    +	for (int attphysnum = relDesc->natts; attphysnum > 0; attphysnum--)
     	{
    -		Form_pg_attribute attr = TupleDescAttr(relDesc, attnum - 1);
    +		Form_pg_attribute attr = TupleDescAttr(relDesc, attphysnum - 1);
     
     		if (attr->attisdropped)
     			continue;
    -		if (bms_is_member(attnum, assignedCols))
    +		if (bms_is_member(attphysnum, assignedCols))
     			continue;
    -		deform.last_scan = attnum;
    +		deform.last_scan = attphysnum;
     		break;
     	}
     
    @@ -668,7 +668,7 @@ ExecBuildUpdateProjection(List *targetList,
     		{
     			/* Just assign from the outer tuple. */
     			scratch.opcode = EEOP_ASSIGN_OUTER_VAR;
    -			scratch.d.assign_var.attnum = outerattnum;
    +			scratch.d.assign_var.attphysnum = outerattnum;
     			scratch.d.assign_var.resultnum = targetattnum - 1;
     			ExprEvalPushStep(state, &scratch);
     		}
    @@ -695,9 +695,9 @@ ExecBuildUpdateProjection(List *targetList,
     	 * Now generate code to copy over any old columns that were not assigned
     	 * to, and to ensure that dropped columns are set to NULL.
     	 */
    -	for (int attnum = 1; attnum <= relDesc->natts; attnum++)
    +	for (int attphysnum = 1; attphysnum <= relDesc->natts; attphysnum++)
     	{
    -		Form_pg_attribute attr = TupleDescAttr(relDesc, attnum - 1);
    +		Form_pg_attribute attr = TupleDescAttr(relDesc, attphysnum - 1);
     
     		if (attr->attisdropped)
     		{
    @@ -710,15 +710,15 @@ ExecBuildUpdateProjection(List *targetList,
     			ExprEvalPushStep(state, &scratch);
     			/* ... then assign it to the result slot */
     			scratch.opcode = EEOP_ASSIGN_TMP;
    -			scratch.d.assign_tmp.resultnum = attnum - 1;
    +			scratch.d.assign_tmp.resultnum = attphysnum - 1;
     			ExprEvalPushStep(state, &scratch);
     		}
    -		else if (!bms_is_member(attnum, assignedCols))
    +		else if (!bms_is_member(attphysnum, assignedCols))
     		{
     			/* Certainly the right type, so needn't check */
     			scratch.opcode = EEOP_ASSIGN_SCAN_VAR;
    -			scratch.d.assign_var.attnum = attnum - 1;
    -			scratch.d.assign_var.resultnum = attnum - 1;
    +			scratch.d.assign_var.attphysnum = attphysnum - 1;
    +			scratch.d.assign_var.resultnum = attphysnum - 1;
     			ExprEvalPushStep(state, &scratch);
     		}
     	}
    @@ -925,7 +925,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
     				else if (variable->varattno <= 0)
     				{
     					/* system column */
    -					scratch.d.var.attnum = variable->varattno;
    +					scratch.d.var.attphysnum = variable->varattno;
     					scratch.d.var.vartype = variable->vartype;
     					switch (variable->varno)
     					{
    @@ -946,7 +946,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
     				else
     				{
     					/* regular user column */
    -					scratch.d.var.attnum = variable->varattno - 1;
    +					scratch.d.var.attphysnum = variable->varattno - 1;
     					scratch.d.var.vartype = variable->vartype;
     					switch (variable->varno)
     					{
    @@ -2890,22 +2890,22 @@ get_last_attnums_walker(Node *node, LastAttnumInfo *info)
     	if (IsA(node, Var))
     	{
     		Var		   *variable = (Var *) node;
    -		AttrNumber	attnum = variable->varattno;
    +		AttrNumber	attphysnum = variable->varattno;
     
     		switch (variable->varno)
     		{
     			case INNER_VAR:
    -				info->last_inner = Max(info->last_inner, attnum);
    +				info->last_inner = Max(info->last_inner, attphysnum);
     				break;
     
     			case OUTER_VAR:
    -				info->last_outer = Max(info->last_outer, attnum);
    +				info->last_outer = Max(info->last_outer, attphysnum);
     				break;
     
     				/* INDEX_VAR is handled by default case */
     
     			default:
    -				info->last_scan = Max(info->last_scan, attnum);
    +				info->last_scan = Max(info->last_scan, attphysnum);
     				break;
     		}
     		return false;
    @@ -4040,7 +4040,7 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
     
     		/* left arg */
     		scratch.opcode = EEOP_INNER_VAR;
    -		scratch.d.var.attnum = attno - 1;
    +		scratch.d.var.attphysnum = attno - 1;
     		scratch.d.var.vartype = latt->atttypid;
     		scratch.resvalue = &fcinfo->args[0].value;
     		scratch.resnull = &fcinfo->args[0].isnull;
    @@ -4048,7 +4048,7 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc,
     
     		/* right arg */
     		scratch.opcode = EEOP_OUTER_VAR;
    -		scratch.d.var.attnum = attno - 1;
    +		scratch.d.var.attphysnum = attno - 1;
     		scratch.d.var.vartype = ratt->atttypid;
     		scratch.resvalue = &fcinfo->args[1].value;
     		scratch.resnull = &fcinfo->args[1].isnull;
    @@ -4174,7 +4174,7 @@ ExecBuildParamSetEqual(TupleDesc desc,
     
     		/* left arg */
     		scratch.opcode = EEOP_INNER_VAR;
    -		scratch.d.var.attnum = attno;
    +		scratch.d.var.attphysnum = attno;
     		scratch.d.var.vartype = att->atttypid;
     		scratch.resvalue = &fcinfo->args[0].value;
     		scratch.resnull = &fcinfo->args[0].isnull;
    @@ -4182,7 +4182,7 @@ ExecBuildParamSetEqual(TupleDesc desc,
     
     		/* right arg */
     		scratch.opcode = EEOP_OUTER_VAR;
    -		scratch.d.var.attnum = attno;
    +		scratch.d.var.attphysnum = attno;
     		scratch.d.var.vartype = att->atttypid;
     		scratch.resvalue = &fcinfo->args[1].value;
     		scratch.resnull = &fcinfo->args[1].isnull;
    diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
    index eaec697bb3..fcc2f346bf 100644
    --- a/src/backend/executor/execExprInterp.c
    +++ b/src/backend/executor/execExprInterp.c
    @@ -151,7 +151,7 @@ static Datum ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnul
     static void ExecInitInterpreter(void);
     
     /* support functions */
    -static void CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype);
    +static void CheckVarSlotCompatibility(TupleTableSlot *slot, int attphysnum, Oid vartype);
     static void CheckOpSlotCompatibility(ExprEvalStep *op, TupleTableSlot *slot);
     static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod,
     									ExprEvalRowtypeCache *rowcache,
    @@ -561,7 +561,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
     
     		EEO_CASE(EEOP_INNER_VAR)
     		{
    -			int			attnum = op->d.var.attnum;
    +			int			attphysnum = op->d.var.attphysnum;
     
     			/*
     			 * Since we already extracted all referenced columns from the
    @@ -569,35 +569,35 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
     			 * directly out of the slot's decomposed-data arrays.  But let's
     			 * have an Assert to check that that did happen.
     			 */
    -			Assert(attnum >= 0 && attnum < innerslot->tts_nvalid);
    -			*op->resvalue = innerslot->tts_values[attnum];
    -			*op->resnull = innerslot->tts_isnull[attnum];
    +			Assert(attphysnum >= 0 && attphysnum < innerslot->tts_nvalid);
    +			*op->resvalue = innerslot->tts_values[attphysnum];
    +			*op->resnull = innerslot->tts_isnull[attphysnum];
     
     			EEO_NEXT();
     		}
     
     		EEO_CASE(EEOP_OUTER_VAR)
     		{
    -			int			attnum = op->d.var.attnum;
    +			int			attphysnum = op->d.var.attphysnum;
     
     			/* See EEOP_INNER_VAR comments */
     
    -			Assert(attnum >= 0 && attnum < outerslot->tts_nvalid);
    -			*op->resvalue = outerslot->tts_values[attnum];
    -			*op->resnull = outerslot->tts_isnull[attnum];
    +			Assert(attphysnum >= 0 && attphysnum < outerslot->tts_nvalid);
    +			*op->resvalue = outerslot->tts_values[attphysnum];
    +			*op->resnull = outerslot->tts_isnull[attphysnum];
     
     			EEO_NEXT();
     		}
     
     		EEO_CASE(EEOP_SCAN_VAR)
     		{
    -			int			attnum = op->d.var.attnum;
    +			int			attphysnum = op->d.var.attphysnum;
     
     			/* See EEOP_INNER_VAR comments */
     
    -			Assert(attnum >= 0 && attnum < scanslot->tts_nvalid);
    -			*op->resvalue = scanslot->tts_values[attnum];
    -			*op->resnull = scanslot->tts_isnull[attnum];
    +			Assert(attphysnum >= 0 && attphysnum < scanslot->tts_nvalid);
    +			*op->resvalue = scanslot->tts_values[attphysnum];
    +			*op->resnull = scanslot->tts_isnull[attphysnum];
     
     			EEO_NEXT();
     		}
    @@ -631,16 +631,16 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
     		EEO_CASE(EEOP_ASSIGN_INNER_VAR)
     		{
     			int			resultnum = op->d.assign_var.resultnum;
    -			int			attnum = op->d.assign_var.attnum;
    +			int			attphysnum = op->d.assign_var.attphysnum;
     
     			/*
     			 * We do not need CheckVarSlotCompatibility here; that was taken
     			 * care of at compilation time.  But see EEOP_INNER_VAR comments.
     			 */
    -			Assert(attnum >= 0 && attnum < innerslot->tts_nvalid);
    +			Assert(attphysnum >= 0 && attphysnum < innerslot->tts_nvalid);
     			Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts);
    -			resultslot->tts_values[resultnum] = innerslot->tts_values[attnum];
    -			resultslot->tts_isnull[resultnum] = innerslot->tts_isnull[attnum];
    +			resultslot->tts_values[resultnum] = innerslot->tts_values[attphysnum];
    +			resultslot->tts_isnull[resultnum] = innerslot->tts_isnull[attphysnum];
     
     			EEO_NEXT();
     		}
    @@ -648,16 +648,16 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
     		EEO_CASE(EEOP_ASSIGN_OUTER_VAR)
     		{
     			int			resultnum = op->d.assign_var.resultnum;
    -			int			attnum = op->d.assign_var.attnum;
    +			int			attphysnum = op->d.assign_var.attphysnum;
     
     			/*
     			 * We do not need CheckVarSlotCompatibility here; that was taken
     			 * care of at compilation time.  But see EEOP_INNER_VAR comments.
     			 */
    -			Assert(attnum >= 0 && attnum < outerslot->tts_nvalid);
    +			Assert(attphysnum >= 0 && attphysnum < outerslot->tts_nvalid);
     			Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts);
    -			resultslot->tts_values[resultnum] = outerslot->tts_values[attnum];
    -			resultslot->tts_isnull[resultnum] = outerslot->tts_isnull[attnum];
    +			resultslot->tts_values[resultnum] = outerslot->tts_values[attphysnum];
    +			resultslot->tts_isnull[resultnum] = outerslot->tts_isnull[attphysnum];
     
     			EEO_NEXT();
     		}
    @@ -665,16 +665,16 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
     		EEO_CASE(EEOP_ASSIGN_SCAN_VAR)
     		{
     			int			resultnum = op->d.assign_var.resultnum;
    -			int			attnum = op->d.assign_var.attnum;
    +			int			attphysnum = op->d.assign_var.attphysnum;
     
     			/*
     			 * We do not need CheckVarSlotCompatibility here; that was taken
     			 * care of at compilation time.  But see EEOP_INNER_VAR comments.
     			 */
    -			Assert(attnum >= 0 && attnum < scanslot->tts_nvalid);
    +			Assert(attphysnum >= 0 && attphysnum < scanslot->tts_nvalid);
     			Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts);
    -			resultslot->tts_values[resultnum] = scanslot->tts_values[attnum];
    -			resultslot->tts_isnull[resultnum] = scanslot->tts_isnull[attnum];
    +			resultslot->tts_values[resultnum] = scanslot->tts_values[attphysnum];
    +			resultslot->tts_isnull[resultnum] = scanslot->tts_isnull[attphysnum];
     
     			EEO_NEXT();
     		}
    @@ -1879,25 +1879,25 @@ CheckExprStillValid(ExprState *state, ExprContext *econtext)
     		{
     			case EEOP_INNER_VAR:
     				{
    -					int			attnum = op->d.var.attnum;
    +					int			attphysnum = op->d.var.attphysnum;
     
    -					CheckVarSlotCompatibility(innerslot, attnum + 1, op->d.var.vartype);
    +					CheckVarSlotCompatibility(innerslot, attphysnum + 1, op->d.var.vartype);
     					break;
     				}
     
     			case EEOP_OUTER_VAR:
     				{
    -					int			attnum = op->d.var.attnum;
    +					int			attphysnum = op->d.var.attphysnum;
     
    -					CheckVarSlotCompatibility(outerslot, attnum + 1, op->d.var.vartype);
    +					CheckVarSlotCompatibility(outerslot, attphysnum + 1, op->d.var.vartype);
     					break;
     				}
     
     			case EEOP_SCAN_VAR:
     				{
    -					int			attnum = op->d.var.attnum;
    +					int			attphysnum = op->d.var.attphysnum;
     
    -					CheckVarSlotCompatibility(scanslot, attnum + 1, op->d.var.vartype);
    +					CheckVarSlotCompatibility(scanslot, attphysnum + 1, op->d.var.vartype);
     					break;
     				}
     			default:
    @@ -1912,7 +1912,7 @@ CheckExprStillValid(ExprState *state, ExprContext *econtext)
      * since the expression tree has been created.
      */
     static void
    -CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype)
    +CheckVarSlotCompatibility(TupleTableSlot *slot, int attphysnum, Oid vartype)
     {
     	/*
     	 * What we have to check for here is the possibility of an attribute
    @@ -1931,28 +1931,28 @@ CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype)
     	 * System attributes don't require checking since their types never
     	 * change.
     	 */
    -	if (attnum > 0)
    +	if (attphysnum > 0)
     	{
     		TupleDesc	slot_tupdesc = slot->tts_tupleDescriptor;
     		Form_pg_attribute attr;
     
    -		if (attnum > slot_tupdesc->natts)	/* should never happen */
    +		if (attphysnum > slot_tupdesc->natts)	/* should never happen */
     			elog(ERROR, "attribute number %d exceeds number of columns %d",
    -				 attnum, slot_tupdesc->natts);
    +				 attphysnum, slot_tupdesc->natts);
     
    -		attr = TupleDescAttr(slot_tupdesc, attnum - 1);
    +		attr = TupleDescAttr(slot_tupdesc, attphysnum - 1);
     
     		if (attr->attisdropped)
     			ereport(ERROR,
     					(errcode(ERRCODE_UNDEFINED_COLUMN),
     					 errmsg("attribute %d of type %s has been dropped",
    -							attnum, format_type_be(slot_tupdesc->tdtypeid))));
    +							attphysnum, format_type_be(slot_tupdesc->tdtypeid))));
     
     		if (vartype != attr->atttypid)
     			ereport(ERROR,
     					(errcode(ERRCODE_DATATYPE_MISMATCH),
     					 errmsg("attribute %d of type %s has wrong type",
    -							attnum, format_type_be(slot_tupdesc->tdtypeid)),
    +							attphysnum, format_type_be(slot_tupdesc->tdtypeid)),
     					 errdetail("Table has type %s, but query expects %s.",
     							   format_type_be(attr->atttypid),
     							   format_type_be(vartype))));
    @@ -2078,16 +2078,16 @@ static pg_attribute_always_inline Datum
     ExecJustVarImpl(ExprState *state, TupleTableSlot *slot, bool *isnull)
     {
     	ExprEvalStep *op = &state->steps[1];
    -	int			attnum = op->d.var.attnum + 1;
    +	int			attphysnum = op->d.var.attphysnum + 1;
     
     	CheckOpSlotCompatibility(&state->steps[0], slot);
     
     	/*
     	 * Since we use slot_getattr(), we don't need to implement the FETCHSOME
    -	 * step explicitly, and we also needn't Assert that the attnum is in range
    +	 * step explicitly, and we also needn't Assert that the attphysnum is in range
     	 * --- slot_getattr() will take care of any problems.
     	 */
    -	return slot_getattr(slot, attnum, isnull);
    +	return slot_getattr(slot, attphysnum, isnull);
     }
     
     /* Simple reference to inner Var */
    @@ -2116,7 +2116,7 @@ static pg_attribute_always_inline Datum
     ExecJustAssignVarImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull)
     {
     	ExprEvalStep *op = &state->steps[1];
    -	int			attnum = op->d.assign_var.attnum + 1;
    +	int			attphysnum = op->d.assign_var.attphysnum + 1;
     	int			resultnum = op->d.assign_var.resultnum;
     	TupleTableSlot *outslot = state->resultslot;
     
    @@ -2127,13 +2127,13 @@ ExecJustAssignVarImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull)
     	 * at compilation time.
     	 *
     	 * Since we use slot_getattr(), we don't need to implement the FETCHSOME
    -	 * step explicitly, and we also needn't Assert that the attnum is in range
    +	 * step explicitly, and we also needn't Assert that the attphysnum is in range
     	 * --- slot_getattr() will take care of any problems.  Nonetheless, check
     	 * that resultnum is in range.
     	 */
     	Assert(resultnum >= 0 && resultnum < outslot->tts_tupleDescriptor->natts);
     	outslot->tts_values[resultnum] =
    -		slot_getattr(inslot, attnum, &outslot->tts_isnull[resultnum]);
    +		slot_getattr(inslot, attphysnum, &outslot->tts_isnull[resultnum]);
     	return 0;
     }
     
    @@ -2211,7 +2211,7 @@ static pg_attribute_always_inline Datum
     ExecJustVarVirtImpl(ExprState *state, TupleTableSlot *slot, bool *isnull)
     {
     	ExprEvalStep *op = &state->steps[0];
    -	int			attnum = op->d.var.attnum;
    +	int			attphysnum = op->d.var.attphysnum;
     
     	/*
     	 * As it is guaranteed that a virtual slot is used, there never is a need
    @@ -2221,11 +2221,11 @@ ExecJustVarVirtImpl(ExprState *state, TupleTableSlot *slot, bool *isnull)
     	 */
     	Assert(TTS_IS_VIRTUAL(slot));
     	Assert(TTS_FIXED(slot));
    -	Assert(attnum >= 0 && attnum < slot->tts_nvalid);
    +	Assert(attphysnum >= 0 && attphysnum < slot->tts_nvalid);
     
    -	*isnull = slot->tts_isnull[attnum];
    +	*isnull = slot->tts_isnull[attphysnum];
     
    -	return slot->tts_values[attnum];
    +	return slot->tts_values[attphysnum];
     }
     
     /* Like ExecJustInnerVar, optimized for virtual slots */
    @@ -2254,7 +2254,7 @@ static pg_attribute_always_inline Datum
     ExecJustAssignVarVirtImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull)
     {
     	ExprEvalStep *op = &state->steps[0];
    -	int			attnum = op->d.assign_var.attnum;
    +	int			attphysnum = op->d.assign_var.attphysnum;
     	int			resultnum = op->d.assign_var.resultnum;
     	TupleTableSlot *outslot = state->resultslot;
     
    @@ -2262,11 +2262,11 @@ ExecJustAssignVarVirtImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull
     
     	Assert(TTS_IS_VIRTUAL(inslot));
     	Assert(TTS_FIXED(inslot));
    -	Assert(attnum >= 0 && attnum < inslot->tts_nvalid);
    +	Assert(attphysnum >= 0 && attphysnum < inslot->tts_nvalid);
     	Assert(resultnum >= 0 && resultnum < outslot->tts_tupleDescriptor->natts);
     
    -	outslot->tts_values[resultnum] = inslot->tts_values[attnum];
    -	outslot->tts_isnull[resultnum] = inslot->tts_isnull[attnum];
    +	outslot->tts_values[resultnum] = inslot->tts_values[attphysnum];
    +	outslot->tts_isnull[resultnum] = inslot->tts_isnull[attphysnum];
     
     	return 0;
     }
    @@ -4036,11 +4036,11 @@ ExecEvalGroupingFunc(ExprState *state, ExprEvalStep *op)
     
     	foreach(lc, op->d.grouping_func.clauses)
     	{
    -		int			attnum = lfirst_int(lc);
    +		int			attphysnum = lfirst_int(lc);
     
     		result <<= 1;
     
    -		if (!bms_is_member(attnum, grouped_cols))
    +		if (!bms_is_member(attphysnum, grouped_cols))
     			result |= 1;
     	}
     
    @@ -4303,7 +4303,7 @@ ExecEvalSysVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
     
     	/* slot_getsysattr has sufficient defenses against bad attnums */
     	d = slot_getsysattr(slot,
    -						op->d.var.attnum,
    +						op->d.var.attphysnum,
     						op->resnull);
     	*op->resvalue = d;
     	/* this ought to be unreachable, but it's cheap enough to check */
    diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
    index ef2fd46092..045c25e634 100644
    --- a/src/backend/executor/execMain.c
    +++ b/src/backend/executor/execMain.c
    @@ -2264,9 +2264,9 @@ ExecBuildSlotValueDescription(Oid reloid,
     			 * for the column.  If not, omit this column from the error
     			 * message.
     			 */
    -			aclresult = pg_attribute_aclcheck(reloid, att->attnum,
    +			aclresult = pg_attribute_aclcheck(reloid, att->attphysnum,
     											  GetUserId(), ACL_SELECT);
    -			if (bms_is_member(att->attnum - FirstLowInvalidHeapAttributeNumber,
    +			if (bms_is_member(att->attphysnum - FirstLowInvalidHeapAttributeNumber,
     							  modifiedCols) || aclresult == ACLCHECK_OK)
     			{
     				column_perm = any_perm = true;
    diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
    index e03ea27299..507212a9a8 100644
    --- a/src/backend/executor/execPartition.c
    +++ b/src/backend/executor/execPartition.c
    @@ -1471,15 +1471,15 @@ ExecBuildSlotPartitionKeyDescription(Relation rel,
     		 */
     		for (i = 0; i < partnatts; i++)
     		{
    -			AttrNumber	attnum = get_partition_col_attnum(key, i);
    +			AttrNumber	attphysnum = get_partition_col_attnum(key, i);
     
     			/*
     			 * If this partition key column is an expression, we return no
     			 * detail rather than try to figure out what column(s) the
     			 * expression includes and if the user has SELECT rights on them.
     			 */
    -			if (attnum == InvalidAttrNumber ||
    -				pg_attribute_aclcheck(relid, attnum, GetUserId(),
    +			if (attphysnum == InvalidAttrNumber ||
    +				pg_attribute_aclcheck(relid, attphysnum, GetUserId(),
     									  ACL_SELECT) != ACLCHECK_OK)
     				return NULL;
     		}
    diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
    index 06ac253ea0..c94f45491f 100644
    --- a/src/backend/executor/execTuples.c
    +++ b/src/backend/executor/execTuples.c
    @@ -137,7 +137,7 @@ tts_virtual_getsomeattrs(TupleTableSlot *slot, int natts)
      * here, but provide a user-friendly message if we do.
      */
     static Datum
    -tts_virtual_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
    +tts_virtual_getsysattr(TupleTableSlot *slot, int attphysnum, bool *isnull)
     {
     	Assert(!TTS_EMPTY(slot));
     
    @@ -337,7 +337,7 @@ tts_heap_getsomeattrs(TupleTableSlot *slot, int natts)
     }
     
     static Datum
    -tts_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
    +tts_heap_getsysattr(TupleTableSlot *slot, int attphysnum, bool *isnull)
     {
     	HeapTupleTableSlot *hslot = (HeapTupleTableSlot *) slot;
     
    @@ -352,7 +352,7 @@ tts_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot retrieve a system column in this context")));
     
    -	return heap_getsysattr(hslot->tuple, attnum,
    +	return heap_getsysattr(hslot->tuple, attphysnum,
     						   slot->tts_tupleDescriptor, isnull);
     }
     
    @@ -512,7 +512,7 @@ tts_minimal_getsomeattrs(TupleTableSlot *slot, int natts)
     }
     
     static Datum
    -tts_minimal_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
    +tts_minimal_getsysattr(TupleTableSlot *slot, int attphysnum, bool *isnull)
     {
     	Assert(!TTS_EMPTY(slot));
     
    @@ -696,7 +696,7 @@ tts_buffer_heap_getsomeattrs(TupleTableSlot *slot, int natts)
     }
     
     static Datum
    -tts_buffer_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
    +tts_buffer_heap_getsysattr(TupleTableSlot *slot, int attphysnum, bool *isnull)
     {
     	BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot;
     
    @@ -711,7 +711,7 @@ tts_buffer_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
     				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     				 errmsg("cannot retrieve a system column in this context")));
     
    -	return heap_getsysattr(bslot->base.tuple, attnum,
    +	return heap_getsysattr(bslot->base.tuple, attphysnum,
     						   slot->tts_tupleDescriptor, isnull);
     }
     
    @@ -930,7 +930,7 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
     	bool	   *isnull = slot->tts_isnull;
     	HeapTupleHeader tup = tuple->t_data;
     	bool		hasnulls = HeapTupleHasNulls(tuple);
    -	int			attnum;
    +	int			attphysnum;
     	char	   *tp;				/* ptr to tuple data */
     	uint32		off;			/* offset in tuple data */
     	bits8	   *bp = tup->t_bits;	/* ptr to null bitmap in tuple */
    @@ -943,8 +943,8 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
     	 * Check whether the first call for this tuple, and initialize or restore
     	 * loop state.
     	 */
    -	attnum = slot->tts_nvalid;
    -	if (attnum == 0)
    +	attphysnum = slot->tts_nvalid;
    +	if (attphysnum == 0)
     	{
     		/* Start from the first attribute */
     		off = 0;
    @@ -959,19 +959,19 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
     
     	tp = (char *) tup + tup->t_hoff;
     
    -	for (; attnum < natts; attnum++)
    +	for (; attphysnum < natts; attphysnum++)
     	{
    -		Form_pg_attribute thisatt = TupleDescAttr(tupleDesc, attnum);
    +		Form_pg_attribute thisatt = TupleDescAttr(tupleDesc, attphysnum);
     
    -		if (hasnulls && att_isnull(attnum, bp))
    +		if (hasnulls && att_isnull(attphysnum, bp))
     		{
    -			values[attnum] = (Datum) 0;
    -			isnull[attnum] = true;
    +			values[attphysnum] = (Datum) 0;
    +			isnull[attphysnum] = true;
     			slow = true;		/* can't use attcacheoff anymore */
     			continue;
     		}
     
    -		isnull[attnum] = false;
    +		isnull[attphysnum] = false;
     
     		if (!slow && thisatt->attcacheoff >= 0)
     			off = thisatt->attcacheoff;
    @@ -1002,7 +1002,7 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
     				thisatt->attcacheoff = off;
     		}
     
    -		values[attnum] = fetchatt(thisatt, tp + off);
    +		values[attphysnum] = fetchatt(thisatt, tp + off);
     
     		off = att_addlength_pointer(off, thisatt->attlen, tp + off);
     
    @@ -1013,7 +1013,7 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
     	/*
     	 * Save state for next execution
     	 */
    -	slot->tts_nvalid = attnum;
    +	slot->tts_nvalid = attphysnum;
     	*offp = off;
     	if (slow)
     		slot->tts_flags |= TTS_FLAG_SLOW;
    @@ -1899,26 +1899,26 @@ slot_getmissingattrs(TupleTableSlot *slot, int startAttNum, int lastAttNum)
      * slot_getsomeattrs_int - workhorse for slot_getsomeattrs()
      */
     void
    -slot_getsomeattrs_int(TupleTableSlot *slot, int attnum)
    +slot_getsomeattrs_int(TupleTableSlot *slot, int attphysnum)
     {
     	/* Check for caller errors */
    -	Assert(slot->tts_nvalid < attnum);	/* checked in slot_getsomeattrs */
    -	Assert(attnum > 0);
    +	Assert(slot->tts_nvalid < attphysnum);	/* checked in slot_getsomeattrs */
    +	Assert(attphysnum > 0);
     
    -	if (unlikely(attnum > slot->tts_tupleDescriptor->natts))
    -		elog(ERROR, "invalid attribute number %d", attnum);
    +	if (unlikely(attphysnum > slot->tts_tupleDescriptor->natts))
    +		elog(ERROR, "invalid attribute number %d", attphysnum);
     
     	/* Fetch as many attributes as possible from the underlying tuple. */
    -	slot->tts_ops->getsomeattrs(slot, attnum);
    +	slot->tts_ops->getsomeattrs(slot, attphysnum);
     
     	/*
     	 * If the underlying tuple doesn't have enough attributes, tuple
     	 * descriptor must have the missing attributes.
     	 */
    -	if (unlikely(slot->tts_nvalid < attnum))
    +	if (unlikely(slot->tts_nvalid < attphysnum))
     	{
    -		slot_getmissingattrs(slot, slot->tts_nvalid, attnum);
    -		slot->tts_nvalid = attnum;
    +		slot_getmissingattrs(slot, slot->tts_nvalid, attphysnum);
    +		slot->tts_nvalid = attphysnum;
     	}
     }
     
    diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
    index 9df1f81ea8..c5caa4e20b 100644
    --- a/src/backend/executor/execUtils.c
    +++ b/src/backend/executor/execUtils.c
    @@ -1054,7 +1054,7 @@ GetAttributeByName(HeapTupleHeader tuple, const char *attname, bool *isNull)
     
     		if (namestrcmp(&(att->attname), attname) == 0)
     		{
    -			attrno = att->attnum;
    +			attrno = att->attphysnum;
     			break;
     		}
     	}
    diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
    index 139b2bd5f9..c94b3ca7cd 100644
    --- a/src/backend/executor/nodeAgg.c
    +++ b/src/backend/executor/nodeAgg.c
    @@ -1269,10 +1269,10 @@ prepare_projection_slot(AggState *aggstate, TupleTableSlot *slot, int currentSet
     
     			foreach(lc, aggstate->all_grouped_cols)
     			{
    -				int			attnum = lfirst_int(lc);
    +				int			attphysnum = lfirst_int(lc);
     
    -				if (!bms_is_member(attnum, grouped_cols))
    -					slot->tts_isnull[attnum - 1] = true;
    +				if (!bms_is_member(attphysnum, grouped_cols))
    +					slot->tts_isnull[attphysnum - 1] = true;
     			}
     		}
     	}
    @@ -1595,10 +1595,10 @@ find_hash_columns(AggState *aggstate)
     
     			foreach(lc, aggstate->all_grouped_cols)
     			{
    -				int			attnum = lfirst_int(lc);
    +				int			attphysnum = lfirst_int(lc);
     
    -				if (!bms_is_member(attnum, grouped_cols))
    -					colnos = bms_del_member(colnos, attnum);
    +				if (!bms_is_member(attphysnum, grouped_cols))
    +					colnos = bms_del_member(colnos, attphysnum);
     			}
     		}
     
    diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
    index 29bc26669b..bdc61e8925 100644
    --- a/src/backend/executor/spi.c
    +++ b/src/backend/executor/spi.c
    @@ -1101,7 +1101,7 @@ SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc)
     }
     
     HeapTuple
    -SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
    +SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attphysnum,
     				Datum *Values, const char *Nulls)
     {
     	MemoryContext oldcxt;
    @@ -1111,7 +1111,7 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
     	bool	   *n;
     	int			i;
     
    -	if (rel == NULL || tuple == NULL || natts < 0 || attnum == NULL || Values == NULL)
    +	if (rel == NULL || tuple == NULL || natts < 0 || attphysnum == NULL || Values == NULL)
     	{
     		SPI_result = SPI_ERROR_ARGUMENT;
     		return NULL;
    @@ -1137,13 +1137,13 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
     	/* replace values and nulls */
     	for (i = 0; i < natts; i++)
     	{
    -		if (attnum[i] <= 0 || attnum[i] > numberOfAttributes)
    +		if (attphysnum[i] <= 0 || attphysnum[i] > numberOfAttributes)
     			break;
    -		v[attnum[i] - 1] = Values[i];
    -		n[attnum[i] - 1] = (Nulls && Nulls[i] == 'n');
    +		v[attphysnum[i] - 1] = Values[i];
    +		n[attphysnum[i] - 1] = (Nulls && Nulls[i] == 'n');
     	}
     
    -	if (i == natts)				/* no errors in *attnum */
    +	if (i == natts)				/* no errors in *attphysnum */
     	{
     		mtuple = heap_form_tuple(rel->rd_att, v, n);
     
    @@ -1186,7 +1186,7 @@ SPI_fnumber(TupleDesc tupdesc, const char *fname)
     
     	sysatt = SystemAttributeByName(fname);
     	if (sysatt != NULL)
    -		return sysatt->attnum;
    +		return sysatt->attphysnum;
     
     	/* SPI_ERROR_NOATTRIBUTE is different from all sys column numbers */
     	return SPI_ERROR_NOATTRIBUTE;
    diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c
    index cf222fc3e9..c064fe50cd 100644
    --- a/src/backend/foreign/foreign.c
    +++ b/src/backend/foreign/foreign.c
    @@ -284,20 +284,20 @@ GetForeignTable(Oid relid)
      * as list of DefElem.
      */
     List *
    -GetForeignColumnOptions(Oid relid, AttrNumber attnum)
    +GetForeignColumnOptions(Oid relid, AttrNumber attphysnum)
     {
     	List	   *options;
     	HeapTuple	tp;
     	Datum		datum;
     	bool		isnull;
     
    -	tp = SearchSysCache2(ATTNUM,
    +	tp = SearchSysCache2(ATTPHYSNUM,
     						 ObjectIdGetDatum(relid),
    -						 Int16GetDatum(attnum));
    +						 Int16GetDatum(attphysnum));
     	if (!HeapTupleIsValid(tp))
     		elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -			 attnum, relid);
    -	datum = SysCacheGetAttr(ATTNUM,
    +			 attphysnum, relid);
    +	datum = SysCacheGetAttr(ATTPHYSNUM,
     							tp,
     							Anum_pg_attribute_attfdwoptions,
     							&isnull);
    diff --git a/src/backend/jit/llvm/llvmjit_deform.c b/src/backend/jit/llvm/llvmjit_deform.c
    index 661f15272b..67e958a58a 100644
    --- a/src/backend/jit/llvm/llvmjit_deform.c
    +++ b/src/backend/jit/llvm/llvmjit_deform.c
    @@ -87,7 +87,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     	/* if true, known_alignment describes definite offset of column */
     	bool		attguaranteedalign = true;
     
    -	int			attnum;
    +	int			attphysnum;
     
     	/* virtual tuples never need deforming, so don't generate code */
     	if (ops == &TTSOpsVirtual)
    @@ -106,9 +106,9 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     	 * Check which columns have to exist, so we don't have to check the row's
     	 * natts unnecessarily.
     	 */
    -	for (attnum = 0; attnum < desc->natts; attnum++)
    +	for (attphysnum = 0; attphysnum < desc->natts; attphysnum++)
     	{
    -		Form_pg_attribute att = TupleDescAttr(desc, attnum);
    +		Form_pg_attribute att = TupleDescAttr(desc, attphysnum);
     
     		/*
     		 * If the column is declared NOT NULL then it must be present in every
    @@ -124,7 +124,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     		if (att->attnotnull &&
     			!att->atthasmissing &&
     			!att->attisdropped)
    -			guaranteed_column_number = attnum;
    +			guaranteed_column_number = attphysnum;
     	}
     
     	/* Create the signature and function */
    @@ -280,20 +280,20 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     	}
     
     	/* build the basic block for each attribute, need them as jump target */
    -	for (attnum = 0; attnum < natts; attnum++)
    +	for (attphysnum = 0; attphysnum < natts; attphysnum++)
     	{
    -		attcheckattnoblocks[attnum] =
    -			l_bb_append_v(v_deform_fn, "block.attr.%d.attcheckattno", attnum);
    -		attstartblocks[attnum] =
    -			l_bb_append_v(v_deform_fn, "block.attr.%d.start", attnum);
    -		attisnullblocks[attnum] =
    -			l_bb_append_v(v_deform_fn, "block.attr.%d.attisnull", attnum);
    -		attcheckalignblocks[attnum] =
    -			l_bb_append_v(v_deform_fn, "block.attr.%d.attcheckalign", attnum);
    -		attalignblocks[attnum] =
    -			l_bb_append_v(v_deform_fn, "block.attr.%d.align", attnum);
    -		attstoreblocks[attnum] =
    -			l_bb_append_v(v_deform_fn, "block.attr.%d.store", attnum);
    +		attcheckattnoblocks[attphysnum] =
    +			l_bb_append_v(v_deform_fn, "block.attr.%d.attcheckattno", attphysnum);
    +		attstartblocks[attphysnum] =
    +			l_bb_append_v(v_deform_fn, "block.attr.%d.start", attphysnum);
    +		attisnullblocks[attphysnum] =
    +			l_bb_append_v(v_deform_fn, "block.attr.%d.attisnull", attphysnum);
    +		attcheckalignblocks[attphysnum] =
    +			l_bb_append_v(v_deform_fn, "block.attr.%d.attcheckalign", attphysnum);
    +		attalignblocks[attphysnum] =
    +			l_bb_append_v(v_deform_fn, "block.attr.%d.align", attphysnum);
    +		attstoreblocks[attphysnum] =
    +			l_bb_append_v(v_deform_fn, "block.attr.%d.store", attphysnum);
     	}
     
     	/*
    @@ -350,11 +350,11 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     		LLVMValueRef v_switch = LLVMBuildSwitch(b, v_nvalid,
     												b_dead, natts);
     
    -		for (attnum = 0; attnum < natts; attnum++)
    +		for (attphysnum = 0; attphysnum < natts; attphysnum++)
     		{
    -			LLVMValueRef v_attno = l_int16_const(attnum);
    +			LLVMValueRef v_attno = l_int16_const(attphysnum);
     
    -			LLVMAddCase(v_switch, v_attno, attcheckattnoblocks[attnum]);
    +			LLVMAddCase(v_switch, v_attno, attcheckattnoblocks[attphysnum]);
     		}
     	}
     	else
    @@ -370,23 +370,23 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     	 * Iterate over each attribute that needs to be deformed, build code to
     	 * deform it.
     	 */
    -	for (attnum = 0; attnum < natts; attnum++)
    +	for (attphysnum = 0; attphysnum < natts; attphysnum++)
     	{
    -		Form_pg_attribute att = TupleDescAttr(desc, attnum);
    +		Form_pg_attribute att = TupleDescAttr(desc, attphysnum);
     		LLVMValueRef v_incby;
     		int			alignto;
    -		LLVMValueRef l_attno = l_int16_const(attnum);
    +		LLVMValueRef l_attno = l_int16_const(attphysnum);
     		LLVMValueRef v_attdatap;
     		LLVMValueRef v_resultp;
     
     		/* build block checking whether we did all the necessary attributes */
    -		LLVMPositionBuilderAtEnd(b, attcheckattnoblocks[attnum]);
    +		LLVMPositionBuilderAtEnd(b, attcheckattnoblocks[attphysnum]);
     
     		/*
     		 * If this is the first attribute, slot->tts_nvalid was 0. Therefore
     		 * also reset offset to 0, it may be from a previous execution.
     		 */
    -		if (attnum == 0)
    +		if (attphysnum == 0)
     		{
     			LLVMBuildStore(b, l_sizet_const(0), v_offp);
     		}
    @@ -396,9 +396,9 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     		 * that many columns stored). We can avoid the branch if we know
     		 * there's a subsequent NOT NULL column.
     		 */
    -		if (attnum <= guaranteed_column_number)
    +		if (attphysnum <= guaranteed_column_number)
     		{
    -			LLVMBuildBr(b, attstartblocks[attnum]);
    +			LLVMBuildBr(b, attstartblocks[attphysnum]);
     		}
     		else
     		{
    @@ -408,9 +408,9 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     									 l_attno,
     									 v_maxatt,
     									 "heap_natts");
    -			LLVMBuildCondBr(b, v_islast, b_out, attstartblocks[attnum]);
    +			LLVMBuildCondBr(b, v_islast, b_out, attstartblocks[attphysnum]);
     		}
    -		LLVMPositionBuilderAtEnd(b, attstartblocks[attnum]);
    +		LLVMPositionBuilderAtEnd(b, attstartblocks[attphysnum]);
     
     		/*
     		 * Check for nulls if necessary. No need to take missing attributes
    @@ -428,16 +428,16 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     			LLVMValueRef v_nullbyte;
     			LLVMValueRef v_nullbit;
     
    -			b_ifnotnull = attcheckalignblocks[attnum];
    -			b_ifnull = attisnullblocks[attnum];
    +			b_ifnotnull = attcheckalignblocks[attphysnum];
    +			b_ifnull = attisnullblocks[attphysnum];
     
    -			if (attnum + 1 == natts)
    +			if (attphysnum + 1 == natts)
     				b_next = b_out;
     			else
    -				b_next = attcheckattnoblocks[attnum + 1];
    +				b_next = attcheckattnoblocks[attphysnum + 1];
     
    -			v_nullbyteno = l_int32_const(attnum >> 3);
    -			v_nullbytemask = l_int8_const(1 << ((attnum) & 0x07));
    +			v_nullbyteno = l_int32_const(attphysnum >> 3);
    +			v_nullbytemask = l_int8_const(1 << ((attphysnum) & 0x07));
     			v_nullbyte = l_load_gep1(b, v_bits, v_nullbyteno, "attnullbyte");
     
     			v_nullbit = LLVMBuildICmp(b,
    @@ -467,11 +467,11 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     		else
     		{
     			/* nothing to do */
    -			LLVMBuildBr(b, attcheckalignblocks[attnum]);
    -			LLVMPositionBuilderAtEnd(b, attisnullblocks[attnum]);
    -			LLVMBuildBr(b, attcheckalignblocks[attnum]);
    +			LLVMBuildBr(b, attcheckalignblocks[attphysnum]);
    +			LLVMPositionBuilderAtEnd(b, attisnullblocks[attphysnum]);
    +			LLVMBuildBr(b, attcheckalignblocks[attphysnum]);
     		}
    -		LLVMPositionBuilderAtEnd(b, attcheckalignblocks[attnum]);
    +		LLVMPositionBuilderAtEnd(b, attcheckalignblocks[attphysnum]);
     
     		/* determine required alignment */
     		if (att->attalign == TYPALIGN_INT)
    @@ -527,15 +527,15 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     								  v_possible_padbyte, l_int8_const(0),
     								  "ispadbyte");
     				LLVMBuildCondBr(b, v_ispad,
    -								attalignblocks[attnum],
    -								attstoreblocks[attnum]);
    +								attalignblocks[attphysnum],
    +								attstoreblocks[attphysnum]);
     			}
     			else
     			{
    -				LLVMBuildBr(b, attalignblocks[attnum]);
    +				LLVMBuildBr(b, attalignblocks[attphysnum]);
     			}
     
    -			LLVMPositionBuilderAtEnd(b, attalignblocks[attnum]);
    +			LLVMPositionBuilderAtEnd(b, attalignblocks[attphysnum]);
     
     			/* translation of alignment code (cf TYPEALIGN()) */
     			{
    @@ -567,17 +567,17 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     				known_alignment = TYPEALIGN(alignto, known_alignment);
     			}
     
    -			LLVMBuildBr(b, attstoreblocks[attnum]);
    -			LLVMPositionBuilderAtEnd(b, attstoreblocks[attnum]);
    +			LLVMBuildBr(b, attstoreblocks[attphysnum]);
    +			LLVMPositionBuilderAtEnd(b, attstoreblocks[attphysnum]);
     		}
     		else
     		{
    -			LLVMPositionBuilderAtEnd(b, attcheckalignblocks[attnum]);
    -			LLVMBuildBr(b, attalignblocks[attnum]);
    -			LLVMPositionBuilderAtEnd(b, attalignblocks[attnum]);
    -			LLVMBuildBr(b, attstoreblocks[attnum]);
    +			LLVMPositionBuilderAtEnd(b, attcheckalignblocks[attphysnum]);
    +			LLVMBuildBr(b, attalignblocks[attphysnum]);
    +			LLVMPositionBuilderAtEnd(b, attalignblocks[attphysnum]);
    +			LLVMBuildBr(b, attstoreblocks[attphysnum]);
     		}
    -		LLVMPositionBuilderAtEnd(b, attstoreblocks[attnum]);
    +		LLVMPositionBuilderAtEnd(b, attstoreblocks[attphysnum]);
     
     		/*
     		 * Store the current offset if known to be constant. That allows LLVM
    @@ -720,14 +720,14 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
     		 * jump to next block, unless last possible column, or all desired
     		 * (available) attributes have been fetched.
     		 */
    -		if (attnum + 1 == natts)
    +		if (attphysnum + 1 == natts)
     		{
     			/* jump out */
     			LLVMBuildBr(b, b_out);
     		}
     		else
     		{
    -			LLVMBuildBr(b, attcheckattnoblocks[attnum + 1]);
    +			LLVMBuildBr(b, attcheckattnoblocks[attphysnum + 1]);
     		}
     	}
     
    diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
    index b6b6512ef1..f12bff8103 100644
    --- a/src/backend/jit/llvm/llvmjit_expr.c
    +++ b/src/backend/jit/llvm/llvmjit_expr.c
    @@ -372,7 +372,7 @@ llvm_compile_expr(ExprState *state)
     						v_nulls = v_scannulls;
     					}
     
    -					v_attnum = l_int32_const(op->d.var.attnum);
    +					v_attnum = l_int32_const(op->d.var.attphysnum);
     					value = l_load_gep1(b, v_values, v_attnum, "");
     					isnull = l_load_gep1(b, v_nulls, v_attnum, "");
     					LLVMBuildStore(b, value, v_resvaluep);
    @@ -438,7 +438,7 @@ llvm_compile_expr(ExprState *state)
     					}
     
     					/* load data */
    -					v_attnum = l_int32_const(op->d.assign_var.attnum);
    +					v_attnum = l_int32_const(op->d.assign_var.attphysnum);
     					v_value = l_load_gep1(b, v_values, v_attnum, "");
     					v_isnull = l_load_gep1(b, v_nulls, v_attnum, "");
     
    diff --git a/src/backend/optimizer/util/appendinfo.c b/src/backend/optimizer/util/appendinfo.c
    index 9d4bb47027..ca83ecb997 100644
    --- a/src/backend/optimizer/util/appendinfo.c
    +++ b/src/backend/optimizer/util/appendinfo.c
    @@ -150,7 +150,7 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
     			if (!HeapTupleIsValid(newtup))
     				elog(ERROR, "could not find inherited attribute \"%s\" of relation \"%s\"",
     					 attname, RelationGetRelationName(newrelation));
    -			new_attno = ((Form_pg_attribute) GETSTRUCT(newtup))->attnum - 1;
    +			new_attno = ((Form_pg_attribute) GETSTRUCT(newtup))->attphysnum - 1;
     			Assert(new_attno >= 0 && new_attno < newnatts);
     			ReleaseSysCache(newtup);
     
    diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
    index 1bcb875507..5ced631957 100644
    --- a/src/backend/parser/analyze.c
    +++ b/src/backend/parser/analyze.c
    @@ -1246,9 +1246,9 @@ count_rowexpr_columns(ParseState *pstate, Node *expr)
     	if (IsA(expr, Var))
     	{
     		Var		   *var = (Var *) expr;
    -		AttrNumber	attnum = var->varattno;
    +		AttrNumber	attphysnum = var->varattno;
     
    -		if (attnum > 0 && var->vartype == RECORDOID)
    +		if (attphysnum > 0 && var->vartype == RECORDOID)
     		{
     			RangeTblEntry *rte;
     
    @@ -1257,7 +1257,7 @@ count_rowexpr_columns(ParseState *pstate, Node *expr)
     			{
     				/* Subselect-in-FROM: examine sub-select's output expr */
     				TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
    -													attnum);
    +													attphysnum);
     
     				if (ste == NULL || ste->resjunk)
     					return -1;
    diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
    index c655d188c7..d1b0080268 100644
    --- a/src/backend/parser/parse_clause.c
    +++ b/src/backend/parser/parse_clause.c
    @@ -257,11 +257,11 @@ extractRemainingColumns(ParseNamespaceColumn *src_nscolumns,
     {
     	int			colcount = 0;
     	Bitmapset  *prevcols;
    -	int			attnum;
    +	int			attphysnum;
     	ListCell   *lc;
     
     	/*
    -	 * While we could just test "list_member_int(*src_colnos, attnum)" to
    +	 * While we could just test "list_member_int(*src_colnos, attphysnum)" to
     	 * detect already-merged columns in the loop below, that would be O(N^2)
     	 * for a wide input table.  Instead build a bitmapset of just the merged
     	 * USING columns, which we won't add to within the main loop.
    @@ -272,22 +272,22 @@ extractRemainingColumns(ParseNamespaceColumn *src_nscolumns,
     		prevcols = bms_add_member(prevcols, lfirst_int(lc));
     	}
     
    -	attnum = 0;
    +	attphysnum = 0;
     	foreach(lc, src_colnames)
     	{
     		char	   *colname = strVal(lfirst(lc));
     
    -		attnum++;
    +		attphysnum++;
     		/* Non-dropped and not already merged? */
    -		if (colname[0] != '\0' && !bms_is_member(attnum, prevcols))
    +		if (colname[0] != '\0' && !bms_is_member(attphysnum, prevcols))
     		{
     			/* Yes, so emit it as next output column */
    -			*src_colnos = lappend_int(*src_colnos, attnum);
    +			*src_colnos = lappend_int(*src_colnos, attphysnum);
     			*res_colnames = lappend(*res_colnames, lfirst(lc));
     			*res_colvars = lappend(*res_colvars,
    -								   buildVarFromNSColumn(src_nscolumns + attnum - 1));
    +								   buildVarFromNSColumn(src_nscolumns + attphysnum - 1));
     			/* Copy the input relation's nscolumn data for this column */
    -			res_nscolumns[colcount] = src_nscolumns[attnum - 1];
    +			res_nscolumns[colcount] = src_nscolumns[attphysnum - 1];
     			colcount++;
     		}
     	}
    diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
    index 926dcbf30e..27c3abb7ec 100644
    --- a/src/backend/parser/parse_relation.c
    +++ b/src/backend/parser/parse_relation.c
    @@ -566,7 +566,7 @@ GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte, int rtelevelsup)
     static void
     updateFuzzyAttrMatchState(int fuzzy_rte_penalty,
     						  FuzzyAttrMatchState *fuzzystate, RangeTblEntry *rte,
    -						  const char *actual, const char *match, int attnum)
    +						  const char *actual, const char *match, int attphysnum)
     {
     	int			columndistance;
     	int			matchlen;
    @@ -613,7 +613,7 @@ updateFuzzyAttrMatchState(int fuzzy_rte_penalty,
     		/* Store new lowest observed distance for RTE */
     		fuzzystate->distance = columndistance;
     		fuzzystate->rfirst = rte;
    -		fuzzystate->first = attnum;
    +		fuzzystate->first = attphysnum;
     		fuzzystate->rsecond = NULL;
     		fuzzystate->second = InvalidAttrNumber;
     	}
    @@ -640,7 +640,7 @@ updateFuzzyAttrMatchState(int fuzzy_rte_penalty,
     		{
     			/* Record as provisional second match for RTE */
     			fuzzystate->rsecond = rte;
    -			fuzzystate->second = attnum;
    +			fuzzystate->second = attphysnum;
     		}
     		else if (fuzzystate->distance <= MAX_FUZZY_DISTANCE)
     		{
    @@ -650,7 +650,7 @@ updateFuzzyAttrMatchState(int fuzzy_rte_penalty,
     			 * than being associated with a real match)
     			 */
     			fuzzystate->rfirst = rte;
    -			fuzzystate->first = attnum;
    +			fuzzystate->first = attphysnum;
     		}
     	}
     }
    @@ -669,23 +669,23 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem,
     					int sublevels_up, const char *colname, int location)
     {
     	RangeTblEntry *rte = nsitem->p_rte;
    -	int			attnum;
    +	int			attphysnum;
     	Var		   *var;
     
     	/*
     	 * Scan the nsitem's column names (or aliases) for a match.  Complain if
     	 * multiple matches.
     	 */
    -	attnum = scanRTEForColumn(pstate, rte, nsitem->p_names,
    +	attphysnum = scanRTEForColumn(pstate, rte, nsitem->p_names,
     							  colname, location,
     							  0, NULL);
     
    -	if (attnum == InvalidAttrNumber)
    +	if (attphysnum == InvalidAttrNumber)
     		return NULL;			/* Return NULL if no match */
     
     	/* In constraint check, no system column is allowed except tableOid */
     	if (pstate->p_expr_kind == EXPR_KIND_CHECK_CONSTRAINT &&
    -		attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber)
    +		attphysnum < InvalidAttrNumber && attphysnum != TableOidAttributeNumber)
     		ereport(ERROR,
     				(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     				 errmsg("system column \"%s\" reference in check constraint is invalid",
    @@ -694,7 +694,7 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem,
     
     	/* In generated column, no system column is allowed except tableOid */
     	if (pstate->p_expr_kind == EXPR_KIND_GENERATED_COLUMN &&
    -		attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber)
    +		attphysnum < InvalidAttrNumber && attphysnum != TableOidAttributeNumber)
     		ereport(ERROR,
     				(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     				 errmsg("cannot use system column \"%s\" in column generation expression",
    @@ -705,7 +705,7 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem,
     	 * In a MERGE WHEN condition, no system column is allowed except tableOid
     	 */
     	if (pstate->p_expr_kind == EXPR_KIND_MERGE_WHEN &&
    -		attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber)
    +		attphysnum < InvalidAttrNumber && attphysnum != TableOidAttributeNumber)
     		ereport(ERROR,
     				(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
     				 errmsg("cannot use system column \"%s\" in MERGE WHEN condition",
    @@ -713,10 +713,10 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem,
     				 parser_errposition(pstate, location)));
     
     	/* Found a valid match, so build a Var */
    -	if (attnum > InvalidAttrNumber)
    +	if (attphysnum > InvalidAttrNumber)
     	{
     		/* Get attribute data from the ParseNamespaceColumn array */
    -		ParseNamespaceColumn *nscol = &nsitem->p_nscolumns[attnum - 1];
    +		ParseNamespaceColumn *nscol = &nsitem->p_nscolumns[attphysnum - 1];
     
     		/* Complain if dropped column.  See notes in scanRTEForColumn. */
     		if (nscol->p_varno == 0)
    @@ -741,9 +741,9 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem,
     		/* System column, so use predetermined type data */
     		const FormData_pg_attribute *sysatt;
     
    -		sysatt = SystemAttributeDefinition(attnum);
    +		sysatt = SystemAttributeDefinition(attphysnum);
     		var = makeVar(nsitem->p_rtindex,
    -					  attnum,
    +					  attphysnum,
     					  sysatt->atttypid,
     					  sysatt->atttypmod,
     					  sysatt->attcollation,
    @@ -760,7 +760,7 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem,
     /*
      * scanRTEForColumn
      *	  Search the column names of a single RTE for the given name.
    - *	  If found, return the attnum (possibly negative, for a system column);
    + *	  If found, return the attphysnum (possibly negative, for a system column);
      *	  else return InvalidAttrNumber.
      *	  If the name proves ambiguous within this RTE, raise error.
      *
    @@ -789,7 +789,7 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
     				 FuzzyAttrMatchState *fuzzystate)
     {
     	int			result = InvalidAttrNumber;
    -	int			attnum = 0;
    +	int			attphysnum = 0;
     	ListCell   *c;
     
     	/*
    @@ -809,7 +809,7 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
     	{
     		const char *attcolname = strVal(lfirst(c));
     
    -		attnum++;
    +		attphysnum++;
     		if (strcmp(attcolname, colname) == 0)
     		{
     			if (result)
    @@ -818,13 +818,13 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
     						 errmsg("column reference \"%s\" is ambiguous",
     								colname),
     						 parser_errposition(pstate, location)));
    -			result = attnum;
    +			result = attphysnum;
     		}
     
     		/* Update fuzzy match state, if provided. */
     		if (fuzzystate != NULL)
     			updateFuzzyAttrMatchState(fuzzy_rte_penalty, fuzzystate,
    -									  rte, attcolname, colname, attnum);
    +									  rte, attcolname, colname, attphysnum);
     	}
     
     	/*
    @@ -843,14 +843,14 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
     		rte->relkind != RELKIND_COMPOSITE_TYPE)
     	{
     		/* quick check to see if name could be a system column */
    -		attnum = specialAttNum(colname);
    -		if (attnum != InvalidAttrNumber)
    +		attphysnum = specialAttNum(colname);
    +		if (attphysnum != InvalidAttrNumber)
     		{
     			/* now check to see if column actually is defined */
    -			if (SearchSysCacheExists2(ATTNUM,
    +			if (SearchSysCacheExists2(ATTPHYSNUM,
     									  ObjectIdGetDatum(rte->relid),
    -									  Int16GetDatum(attnum)))
    -				result = attnum;
    +									  Int16GetDatum(attphysnum)))
    +				result = attphysnum;
     		}
     	}
     
    @@ -1023,7 +1023,7 @@ markRTEForSelectPriv(ParseState *pstate, int rtindex, AttrNumber col)
     	{
     		/* Make sure the rel as a whole is marked for SELECT access */
     		rte->requiredPerms |= ACL_SELECT;
    -		/* Must offset the attnum to fit in a bitmapset */
    +		/* Must offset the attphysnum to fit in a bitmapset */
     		rte->selectedCols = bms_add_member(rte->selectedCols,
     										   col - FirstLowInvalidHeapAttributeNumber);
     	}
    @@ -2746,7 +2746,7 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
     							ListCell   *l1;
     							ListCell   *l2;
     							ListCell   *l3;
    -							int			attnum = atts_done;
    +							int			attphysnum = atts_done;
     
     							forthree(l1, rtfunc->funccoltypes,
     									 l2, rtfunc->funccoltypmods,
    @@ -2757,9 +2757,9 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
     								Oid			attrcollation = lfirst_oid(l3);
     								Var		   *varnode;
     
    -								attnum++;
    +								attphysnum++;
     								varnode = makeVar(rtindex,
    -												  attnum,
    +												  attphysnum,
     												  attrtype,
     												  attrtypmod,
     												  attrcollation,
    @@ -3181,21 +3181,21 @@ expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem,
      * In particular, it will work on an RTE for a subselect or join, whereas
      * get_attname() only works on real relations.
      *
    - * "*" is returned if the given attnum is InvalidAttrNumber --- this case
    + * "*" is returned if the given attphysnum is InvalidAttrNumber --- this case
      * occurs when a Var represents a whole tuple of a relation.
      */
     char *
    -get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
    +get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attphysnum)
     {
    -	if (attnum == InvalidAttrNumber)
    +	if (attphysnum == InvalidAttrNumber)
     		return "*";
     
     	/*
     	 * If there is a user-written column alias, use it.
     	 */
     	if (rte->alias &&
    -		attnum > 0 && attnum <= list_length(rte->alias->colnames))
    -		return strVal(list_nth(rte->alias->colnames, attnum - 1));
    +		attphysnum > 0 && attphysnum <= list_length(rte->alias->colnames))
    +		return strVal(list_nth(rte->alias->colnames, attphysnum - 1));
     
     	/*
     	 * If the RTE is a relation, go to the system catalogs not the
    @@ -3204,17 +3204,17 @@ get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
     	 * built (which can easily happen for rules).
     	 */
     	if (rte->rtekind == RTE_RELATION)
    -		return get_attname(rte->relid, attnum, false);
    +		return get_attname(rte->relid, attphysnum, false);
     
     	/*
     	 * Otherwise use the column name from eref.  There should always be one.
     	 */
    -	if (attnum > 0 && attnum <= list_length(rte->eref->colnames))
    -		return strVal(list_nth(rte->eref->colnames, attnum - 1));
    +	if (attphysnum > 0 && attphysnum <= list_length(rte->eref->colnames))
    +		return strVal(list_nth(rte->eref->colnames, attphysnum - 1));
     
    -	/* else caller gave us a bogus attnum */
    -	elog(ERROR, "invalid attnum %d for rangetable entry %s",
    -		 attnum, rte->eref->aliasname);
    +	/* else caller gave us a bogus attphysnum */
    +	elog(ERROR, "invalid attphysnum %d for rangetable entry %s",
    +		 attphysnum, rte->eref->aliasname);
     	return NULL;				/* keep compiler quiet */
     }
     
    @@ -3223,7 +3223,7 @@ get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
      *		Check whether attempted attribute ref is to a dropped column
      */
     bool
    -get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
    +get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attphysnum)
     {
     	bool		result;
     
    @@ -3237,12 +3237,12 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
     				HeapTuple	tp;
     				Form_pg_attribute att_tup;
     
    -				tp = SearchSysCache2(ATTNUM,
    +				tp = SearchSysCache2(ATTPHYSNUM,
     									 ObjectIdGetDatum(rte->relid),
    -									 Int16GetDatum(attnum));
    +									 Int16GetDatum(attphysnum));
     				if (!HeapTupleIsValid(tp))	/* shouldn't happen */
     					elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -						 attnum, rte->relid);
    +						 attphysnum, rte->relid);
     				att_tup = (Form_pg_attribute) GETSTRUCT(tp);
     				result = att_tup->attisdropped;
     				ReleaseSysCache(tp);
    @@ -3262,10 +3262,10 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
     		case RTE_NAMEDTUPLESTORE:
     			{
     				/* Check dropped-ness by testing for valid coltype */
    -				if (attnum <= 0 ||
    -					attnum > list_length(rte->coltypes))
    -					elog(ERROR, "invalid varattno %d", attnum);
    -				result = !OidIsValid((list_nth_oid(rte->coltypes, attnum - 1)));
    +				if (attphysnum <= 0 ||
    +					attphysnum > list_length(rte->coltypes))
    +					elog(ERROR, "invalid varattno %d", attphysnum);
    +				result = !OidIsValid((list_nth_oid(rte->coltypes, attphysnum - 1)));
     			}
     			break;
     		case RTE_JOIN:
    @@ -3279,10 +3279,10 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
     				 */
     				Var		   *aliasvar;
     
    -				if (attnum <= 0 ||
    -					attnum > list_length(rte->joinaliasvars))
    -					elog(ERROR, "invalid varattno %d", attnum);
    -				aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
    +				if (attphysnum <= 0 ||
    +					attphysnum > list_length(rte->joinaliasvars))
    +					elog(ERROR, "invalid varattno %d", attphysnum);
    +				aliasvar = (Var *) list_nth(rte->joinaliasvars, attphysnum - 1);
     
     				result = (aliasvar == NULL);
     			}
    @@ -3304,8 +3304,8 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
     				{
     					RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
     
    -					if (attnum > atts_done &&
    -						attnum <= atts_done + rtfunc->funccolcount)
    +					if (attphysnum > atts_done &&
    +						attphysnum <= atts_done + rtfunc->funccolcount)
     					{
     						TupleDesc	tupdesc;
     
    @@ -3317,9 +3317,9 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
     							Form_pg_attribute att_tup;
     
     							Assert(tupdesc);
    -							Assert(attnum - atts_done <= tupdesc->natts);
    +							Assert(attphysnum - atts_done <= tupdesc->natts);
     							att_tup = TupleDescAttr(tupdesc,
    -													attnum - atts_done - 1);
    +													attphysnum - atts_done - 1);
     							return att_tup->attisdropped;
     						}
     						/* Otherwise, it can't have any dropped columns */
    @@ -3329,14 +3329,14 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
     				}
     
     				/* If we get here, must be looking for the ordinality column */
    -				if (rte->funcordinality && attnum == atts_done + 1)
    +				if (rte->funcordinality && attphysnum == atts_done + 1)
     					return false;
     
     				/* this probably can't happen ... */
     				ereport(ERROR,
     						(errcode(ERRCODE_UNDEFINED_COLUMN),
     						 errmsg("column %d of relation \"%s\" does not exist",
    -								attnum,
    +								attphysnum,
     								rte->eref->aliasname)));
     				result = false; /* keep compiler quiet */
     			}
    @@ -3346,7 +3346,7 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
     			ereport(ERROR,
     					(errcode(ERRCODE_UNDEFINED_COLUMN),
     					 errmsg("column %d of relation \"%s\" does not exist",
    -							attnum,
    +							attphysnum,
     							rte->eref->aliasname)));
     			result = false;		/* keep compiler quiet */
     			break;
    @@ -3402,12 +3402,12 @@ get_parse_rowmark(Query *qry, Index rtindex)
     }
     
     /*
    - *	given relation and att name, return attnum of variable
    + *	given relation and att name, return attphysnum of variable
      *
      *	Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
      *
      *	This should only be used if the relation is already
    - *	table_open()'ed.  Use the cache version get_attnum()
    + *	table_open()'ed.  Use the cache version get_attphysnum()
      *	for access to non-opened relations.
      */
     int
    @@ -3448,7 +3448,7 @@ specialAttNum(const char *attname)
     
     	sysatt = SystemAttributeByName(attname);
     	if (sysatt != NULL)
    -		return sysatt->attnum;
    +		return sysatt->attphysnum;
     	return InvalidAttrNumber;
     }
     
    diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
    index 2a1d44b813..cff1cda48d 100644
    --- a/src/backend/parser/parse_target.c
    +++ b/src/backend/parser/parse_target.c
    @@ -347,31 +347,31 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
     {
     	int			netlevelsup;
     	RangeTblEntry *rte;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     
     	if (var == NULL || !IsA(var, Var))
     		return;
     	netlevelsup = var->varlevelsup + levelsup;
     	rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
    -	attnum = var->varattno;
    +	attphysnum = var->varattno;
     
     	switch (rte->rtekind)
     	{
     		case RTE_RELATION:
     			/* It's a table or view, report it */
     			tle->resorigtbl = rte->relid;
    -			tle->resorigcol = attnum;
    +			tle->resorigcol = attphysnum;
     			break;
     		case RTE_SUBQUERY:
     			/* Subselect-in-FROM: copy up from the subselect */
    -			if (attnum != InvalidAttrNumber)
    +			if (attphysnum != InvalidAttrNumber)
     			{
     				TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
    -													attnum);
    +													attphysnum);
     
     				if (ste == NULL || ste->resjunk)
     					elog(ERROR, "subquery %s does not have attribute %d",
    -						 rte->eref->aliasname, attnum);
    +						 rte->eref->aliasname, attphysnum);
     				tle->resorigtbl = ste->resorigtbl;
     				tle->resorigcol = ste->resorigcol;
     			}
    @@ -394,7 +394,7 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
     			 * recursive CTE, and so any markings on the current targetlist
     			 * are not going to affect the results anyway.
     			 */
    -			if (attnum != InvalidAttrNumber && !rte->self_reference)
    +			if (attphysnum != InvalidAttrNumber && !rte->self_reference)
     			{
     				CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
     				TargetEntry *ste;
    @@ -410,14 +410,14 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
     				if (cte->cycle_clause)
     					extra_cols += 2;
     				if (extra_cols &&
    -					attnum > list_length(tl) &&
    -					attnum <= list_length(tl) + extra_cols)
    +					attphysnum > list_length(tl) &&
    +					attphysnum <= list_length(tl) + extra_cols)
     					break;
     
    -				ste = get_tle_by_resno(tl, attnum);
    +				ste = get_tle_by_resno(tl, attphysnum);
     				if (ste == NULL || ste->resjunk)
     					elog(ERROR, "CTE %s does not have attribute %d",
    -						 rte->eref->aliasname, attnum);
    +						 rte->eref->aliasname, attphysnum);
     				tle->resorigtbl = ste->resorigtbl;
     				tle->resorigcol = ste->resorigcol;
     			}
    @@ -745,7 +745,7 @@ transformAssignmentIndirection(ParseState *pstate,
     			Oid			baseTypeId;
     			int32		baseTypeMod;
     			Oid			typrelid;
    -			AttrNumber	attnum;
    +			AttrNumber	attphysnum;
     			Oid			fieldTypeId;
     			int32		fieldTypMod;
     			Oid			fieldCollation;
    @@ -789,22 +789,22 @@ transformAssignmentIndirection(ParseState *pstate,
     								format_type_be(targetTypeId)),
     						 parser_errposition(pstate, location)));
     
    -			attnum = get_attnum(typrelid, strVal(n));
    -			if (attnum == InvalidAttrNumber)
    +			attphysnum = get_attphysnum(typrelid, strVal(n));
    +			if (attphysnum == InvalidAttrNumber)
     				ereport(ERROR,
     						(errcode(ERRCODE_UNDEFINED_COLUMN),
     						 errmsg("cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s",
     								strVal(n), targetName,
     								format_type_be(targetTypeId)),
     						 parser_errposition(pstate, location)));
    -			if (attnum < 0)
    +			if (attphysnum < 0)
     				ereport(ERROR,
     						(errcode(ERRCODE_UNDEFINED_COLUMN),
     						 errmsg("cannot assign to system column \"%s\"",
     								strVal(n)),
     						 parser_errposition(pstate, location)));
     
    -			get_atttypetypmodcoll(typrelid, attnum,
    +			get_atttypetypmodcoll(typrelid, attphysnum,
     								  &fieldTypeId, &fieldTypMod, &fieldCollation);
     
     			/* recurse to create appropriate RHS for field assign */
    @@ -825,7 +825,7 @@ transformAssignmentIndirection(ParseState *pstate,
     			fstore = makeNode(FieldStore);
     			fstore->arg = (Expr *) basenode;
     			fstore->newvals = list_make1(rhs);
    -			fstore->fieldnums = list_make1_int(attnum);
    +			fstore->fieldnums = list_make1_int(attphysnum);
     			fstore->resulttype = baseTypeId;
     
     			/* If target is a domain, apply constraints */
    @@ -1512,7 +1512,7 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
     	TupleDesc	tupleDesc;
     	int			netlevelsup;
     	RangeTblEntry *rte;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	Node	   *expr;
     
     	/* Check my caller didn't mess up */
    @@ -1527,9 +1527,9 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
     	 */
     	netlevelsup = var->varlevelsup + levelsup;
     	rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
    -	attnum = var->varattno;
    +	attphysnum = var->varattno;
     
    -	if (attnum == InvalidAttrNumber)
    +	if (attphysnum == InvalidAttrNumber)
     	{
     		/* Whole-row reference to an RTE, so expand the known fields */
     		List	   *names,
    @@ -1581,11 +1581,11 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
     			{
     				/* Subselect-in-FROM: examine sub-select's output expr */
     				TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
    -													attnum);
    +													attphysnum);
     
     				if (ste == NULL || ste->resjunk)
     					elog(ERROR, "subquery %s does not have attribute %d",
    -						 rte->eref->aliasname, attnum);
    +						 rte->eref->aliasname, attphysnum);
     				expr = (Node *) ste->expr;
     				if (IsA(expr, Var))
     				{
    @@ -1608,8 +1608,8 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
     			break;
     		case RTE_JOIN:
     			/* Join RTE --- recursively inspect the alias variable */
    -			Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
    -			expr = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
    +			Assert(attphysnum > 0 && attphysnum <= list_length(rte->joinaliasvars));
    +			expr = (Node *) list_nth(rte->joinaliasvars, attphysnum - 1);
     			Assert(expr != NULL);
     			/* We intentionally don't strip implicit coercions here */
     			if (IsA(expr, Var))
    @@ -1636,10 +1636,10 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
     				CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
     				TargetEntry *ste;
     
    -				ste = get_tle_by_resno(GetCTETargetList(cte), attnum);
    +				ste = get_tle_by_resno(GetCTETargetList(cte), attphysnum);
     				if (ste == NULL || ste->resjunk)
     					elog(ERROR, "CTE %s does not have attribute %d",
    -						 rte->eref->aliasname, attnum);
    +						 rte->eref->aliasname, attphysnum);
     				expr = (Node *) ste->expr;
     				if (IsA(expr, Var))
     				{
    diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
    index 307114a30d..1959ef3bc1 100644
    --- a/src/backend/parser/parse_type.c
    +++ b/src/backend/parser/parse_type.c
    @@ -89,7 +89,7 @@ LookupTypeNameExtended(ParseState *pstate,
     		RangeVar   *rel = makeRangeVar(NULL, NULL, typeName->location);
     		char	   *field = NULL;
     		Oid			relid;
    -		AttrNumber	attnum;
    +		AttrNumber	attphysnum;
     
     		/* deconstruct the name list */
     		switch (list_length(typeName->names))
    @@ -133,8 +133,8 @@ LookupTypeNameExtended(ParseState *pstate,
     		 * penalty and would also require a permissions check.
     		 */
     		relid = RangeVarGetRelid(rel, NoLock, missing_ok);
    -		attnum = get_attnum(relid, field);
    -		if (attnum == InvalidAttrNumber)
    +		attphysnum = get_attphysnum(relid, field);
    +		if (attphysnum == InvalidAttrNumber)
     		{
     			if (missing_ok)
     				typoid = InvalidOid;
    @@ -147,7 +147,7 @@ LookupTypeNameExtended(ParseState *pstate,
     		}
     		else
     		{
    -			typoid = get_atttype(relid, attnum);
    +			typoid = get_atttype(relid, attphysnum);
     
     			/* this construct should never have an array indicator */
     			Assert(typeName->arrayBounds == NIL);
    diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
    index 1a64a52279..69132f729d 100644
    --- a/src/backend/parser/parse_utilcmd.c
    +++ b/src/backend/parser/parse_utilcmd.c
    @@ -487,7 +487,7 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column,
     	 * owned by this column, and add it to the appropriate list of things to
     	 * be done along with this CREATE/ALTER TABLE.  In a CREATE or ALTER ADD
     	 * COLUMN, it must be done after the statement because we don't know the
    -	 * column's attnum yet.  But if we do have the attnum (in AT_AddIdentity),
    +	 * column's attphysnum yet.  But if we do have the attphysnum (in AT_AddIdentity),
     	 * we can do the marking immediately, which improves some ALTER TABLE
     	 * behaviors.
     	 */
    @@ -1070,7 +1070,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
     			 * find sequence owned by old column; extract sequence parameters;
     			 * build new create sequence command
     			 */
    -			seq_relid = getIdentitySequence(RelationGetRelid(relation), attribute->attnum, false);
    +			seq_relid = getIdentitySequence(RelationGetRelid(relation), attribute->attphysnum, false);
     			seq_options = sequence_options(seq_relid);
     			generateSerialExtraStmts(cxt, def,
     									 InvalidOid, seq_options,
    @@ -1097,7 +1097,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
     		if ((table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) &&
     			(comment = GetComment(attribute->attrelid,
     								  RelationRelationId,
    -								  attribute->attnum)) != NULL)
    +								  attribute->attphysnum)) != NULL)
     		{
     			CommentStmt *stmt = makeNode(CommentStmt);
     
    @@ -1701,20 +1701,20 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
     	for (keyno = 0; keyno < idxrec->indnkeyatts; keyno++)
     	{
     		IndexElem  *iparam;
    -		AttrNumber	attnum = idxrec->indkey.values[keyno];
    +		AttrNumber	attphysnum = idxrec->indkey.values[keyno];
     		Form_pg_attribute attr = TupleDescAttr(RelationGetDescr(source_idx),
     											   keyno);
     		int16		opt = source_idx->rd_indoption[keyno];
     
     		iparam = makeNode(IndexElem);
     
    -		if (AttributeNumberIsValid(attnum))
    +		if (AttributeNumberIsValid(attphysnum))
     		{
     			/* Simple index column */
     			char	   *attname;
     
    -			attname = get_attname(indrelid, attnum, false);
    -			keycoltype = get_atttype(indrelid, attnum);
    +			attname = get_attname(indrelid, attphysnum, false);
    +			keycoltype = get_atttype(indrelid, attphysnum);
     
     			iparam->name = attname;
     			iparam->expr = NULL;
    @@ -1793,18 +1793,18 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
     	for (keyno = idxrec->indnkeyatts; keyno < idxrec->indnatts; keyno++)
     	{
     		IndexElem  *iparam;
    -		AttrNumber	attnum = idxrec->indkey.values[keyno];
    +		AttrNumber	attphysnum = idxrec->indkey.values[keyno];
     		Form_pg_attribute attr = TupleDescAttr(RelationGetDescr(source_idx),
     											   keyno);
     
     		iparam = makeNode(IndexElem);
     
    -		if (AttributeNumberIsValid(attnum))
    +		if (AttributeNumberIsValid(attphysnum))
     		{
     			/* Simple index column */
     			char	   *attname;
     
    -			attname = get_attname(indrelid, attnum, false);
    +			attname = get_attname(indrelid, attphysnum, false);
     
     			iparam->name = attname;
     			iparam->expr = NULL;
    @@ -1922,9 +1922,9 @@ generateClonedExtStatsStmt(RangeVar *heapRel, Oid heapRelid,
     	for (i = 0; i < statsrec->stxkeys.dim1; i++)
     	{
     		StatsElem  *selem = makeNode(StatsElem);
    -		AttrNumber	attnum = statsrec->stxkeys.values[i];
    +		AttrNumber	attphysnum = statsrec->stxkeys.values[i];
     
    -		selem->name = get_attname(heapRelid, attnum, false);
    +		selem->name = get_attname(heapRelid, attphysnum, false);
     		selem->expr = NULL;
     
     		def_names = lappend(def_names, selem);
    @@ -2330,23 +2330,23 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
     
     		for (i = 0; i < index_form->indnatts; i++)
     		{
    -			int16		attnum = index_form->indkey.values[i];
    +			int16		attphysnum = index_form->indkey.values[i];
     			const FormData_pg_attribute *attform;
     			char	   *attname;
     			Oid			defopclass;
     
     			/*
    -			 * We shouldn't see attnum == 0 here, since we already rejected
    +			 * We shouldn't see attphysnum == 0 here, since we already rejected
     			 * expression indexes.  If we do, SystemAttributeDefinition will
     			 * throw an error.
     			 */
    -			if (attnum > 0)
    +			if (attphysnum > 0)
     			{
    -				Assert(attnum <= heap_rel->rd_att->natts);
    -				attform = TupleDescAttr(heap_rel->rd_att, attnum - 1);
    +				Assert(attphysnum <= heap_rel->rd_att->natts);
    +				attform = TupleDescAttr(heap_rel->rd_att, attphysnum - 1);
     			}
     			else
    -				attform = SystemAttributeDefinition(attnum);
    +				attform = SystemAttributeDefinition(attphysnum);
     			attname = pstrdup(NameStr(attform->attname));
     
     			if (i < index_form->indnkeyatts)
    @@ -3400,7 +3400,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
     			case AT_AlterColumnType:
     				{
     					ColumnDef  *def = castNode(ColumnDef, cmd->def);
    -					AttrNumber	attnum;
    +					AttrNumber	attphysnum;
     
     					/*
     					 * For ALTER COLUMN TYPE, transform the USING clause if
    @@ -3417,17 +3417,17 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
     					 * For identity column, create ALTER SEQUENCE command to
     					 * change the data type of the sequence.
     					 */
    -					attnum = get_attnum(relid, cmd->name);
    -					if (attnum == InvalidAttrNumber)
    +					attphysnum = get_attphysnum(relid, cmd->name);
    +					if (attphysnum == InvalidAttrNumber)
     						ereport(ERROR,
     								(errcode(ERRCODE_UNDEFINED_COLUMN),
     								 errmsg("column \"%s\" of relation \"%s\" does not exist",
     										cmd->name, RelationGetRelationName(rel))));
     
    -					if (attnum > 0 &&
    -						TupleDescAttr(tupdesc, attnum - 1)->attidentity)
    +					if (attphysnum > 0 &&
    +						TupleDescAttr(tupdesc, attphysnum - 1)->attidentity)
     					{
    -						Oid			seq_relid = getIdentitySequence(relid, attnum, false);
    +						Oid			seq_relid = getIdentitySequence(relid, attphysnum, false);
     						Oid			typeOid = typenameTypeId(pstate, def->typeName);
     						AlterSeqStmt *altseqstmt = makeNode(AlterSeqStmt);
     
    @@ -3447,21 +3447,21 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
     				{
     					Constraint *def = castNode(Constraint, cmd->def);
     					ColumnDef  *newdef = makeNode(ColumnDef);
    -					AttrNumber	attnum;
    +					AttrNumber	attphysnum;
     
     					newdef->colname = cmd->name;
     					newdef->identity = def->generated_when;
     					cmd->def = (Node *) newdef;
     
    -					attnum = get_attnum(relid, cmd->name);
    -					if (attnum == InvalidAttrNumber)
    +					attphysnum = get_attphysnum(relid, cmd->name);
    +					if (attphysnum == InvalidAttrNumber)
     						ereport(ERROR,
     								(errcode(ERRCODE_UNDEFINED_COLUMN),
     								 errmsg("column \"%s\" of relation \"%s\" does not exist",
     										cmd->name, RelationGetRelationName(rel))));
     
     					generateSerialExtraStmts(&cxt, newdef,
    -											 get_atttype(relid, attnum),
    +											 get_atttype(relid, attphysnum),
     											 def->options, true, true,
     											 NULL, NULL);
     
    @@ -3478,7 +3478,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
     					ListCell   *lc;
     					List	   *newseqopts = NIL;
     					List	   *newdef = NIL;
    -					AttrNumber	attnum;
    +					AttrNumber	attphysnum;
     					Oid			seq_relid;
     
     					/*
    @@ -3495,14 +3495,14 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
     							newseqopts = lappend(newseqopts, def);
     					}
     
    -					attnum = get_attnum(relid, cmd->name);
    -					if (attnum == InvalidAttrNumber)
    +					attphysnum = get_attphysnum(relid, cmd->name);
    +					if (attphysnum == InvalidAttrNumber)
     						ereport(ERROR,
     								(errcode(ERRCODE_UNDEFINED_COLUMN),
     								 errmsg("column \"%s\" of relation \"%s\" does not exist",
     										cmd->name, RelationGetRelationName(rel))));
     
    -					seq_relid = getIdentitySequence(relid, attnum, true);
    +					seq_relid = getIdentitySequence(relid, attphysnum, true);
     
     					if (seq_relid)
     					{
    diff --git a/src/backend/replication/basebackup_copy.c b/src/backend/replication/basebackup_copy.c
    index cabb077240..38d792884e 100644
    --- a/src/backend/replication/basebackup_copy.c
    +++ b/src/backend/replication/basebackup_copy.c
    @@ -346,7 +346,7 @@ SendXlogRecPtrResult(XLogRecPtr ptr, TimeLineID tli)
     	/* Field headers */
     	pq_sendstring(&buf, "recptr");
     	pq_sendint32(&buf, 0);		/* table oid */
    -	pq_sendint16(&buf, 0);		/* attnum */
    +	pq_sendint16(&buf, 0);		/* attphysnum */
     	pq_sendint32(&buf, TEXTOID);	/* type oid */
     	pq_sendint16(&buf, -1);
     	pq_sendint32(&buf, 0);
    @@ -354,7 +354,7 @@ SendXlogRecPtrResult(XLogRecPtr ptr, TimeLineID tli)
     
     	pq_sendstring(&buf, "tli");
     	pq_sendint32(&buf, 0);		/* table oid */
    -	pq_sendint16(&buf, 0);		/* attnum */
    +	pq_sendint16(&buf, 0);		/* attphysnum */
     
     	/*
     	 * int8 may seem like a surprising data type for this, but in theory int4
    @@ -401,7 +401,7 @@ SendTablespaceList(List *tablespaces)
     	/* First field - spcoid */
     	pq_sendstring(&buf, "spcoid");
     	pq_sendint32(&buf, 0);		/* table oid */
    -	pq_sendint16(&buf, 0);		/* attnum */
    +	pq_sendint16(&buf, 0);		/* attphysnum */
     	pq_sendint32(&buf, OIDOID); /* type oid */
     	pq_sendint16(&buf, 4);		/* typlen */
     	pq_sendint32(&buf, 0);		/* typmod */
    diff --git a/src/backend/replication/logical/proto.c b/src/backend/replication/logical/proto.c
    index ff8513e2d2..0e68aa0d9d 100644
    --- a/src/backend/replication/logical/proto.c
    +++ b/src/backend/replication/logical/proto.c
    @@ -47,9 +47,9 @@ static const char *logicalrep_read_namespace(StringInfo in);
      * all columns.
      */
     static bool
    -column_in_column_list(int attnum, Bitmapset *columns)
    +column_in_column_list(int attphysnum, Bitmapset *columns)
     {
    -	return (columns == NULL || bms_is_member(attnum, columns));
    +	return (columns == NULL || bms_is_member(attphysnum, columns));
     }
     
     
    @@ -783,7 +783,7 @@ logicalrep_write_tuple(StringInfo out, Relation rel, TupleTableSlot *slot,
     		if (att->attisdropped || att->attgenerated)
     			continue;
     
    -		if (!column_in_column_list(att->attnum, columns))
    +		if (!column_in_column_list(att->attphysnum, columns))
     			continue;
     
     		nliveatts++;
    @@ -804,7 +804,7 @@ logicalrep_write_tuple(StringInfo out, Relation rel, TupleTableSlot *slot,
     		if (att->attisdropped || att->attgenerated)
     			continue;
     
    -		if (!column_in_column_list(att->attnum, columns))
    +		if (!column_in_column_list(att->attphysnum, columns))
     			continue;
     
     		if (isnull[i])
    @@ -946,7 +946,7 @@ logicalrep_write_attrs(StringInfo out, Relation rel, Bitmapset *columns)
     		if (att->attisdropped || att->attgenerated)
     			continue;
     
    -		if (!column_in_column_list(att->attnum, columns))
    +		if (!column_in_column_list(att->attphysnum, columns))
     			continue;
     
     		nliveatts++;
    @@ -967,12 +967,12 @@ logicalrep_write_attrs(StringInfo out, Relation rel, Bitmapset *columns)
     		if (att->attisdropped || att->attgenerated)
     			continue;
     
    -		if (!column_in_column_list(att->attnum, columns))
    +		if (!column_in_column_list(att->attphysnum, columns))
     			continue;
     
     		/* REPLICA IDENTITY FULL means all columns are sent as part of key. */
     		if (replidentfull ||
    -			bms_is_member(att->attnum - FirstLowInvalidHeapAttributeNumber,
    +			bms_is_member(att->attphysnum - FirstLowInvalidHeapAttributeNumber,
     						  idattrs))
     			flags |= LOGICALREP_IS_REPLICA_IDENTITY;
     
    diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c
    index e989047681..a067446379 100644
    --- a/src/backend/replication/logical/relation.c
    +++ b/src/backend/replication/logical/relation.c
    @@ -290,19 +290,19 @@ logicalrep_rel_mark_updatable(LogicalRepRelMapEntry *entry)
     	i = -1;
     	while ((i = bms_next_member(idkey, i)) >= 0)
     	{
    -		int			attnum = i + FirstLowInvalidHeapAttributeNumber;
    +		int			attphysnum = i + FirstLowInvalidHeapAttributeNumber;
     
    -		if (!AttrNumberIsForUserDefinedAttr(attnum))
    +		if (!AttrNumberIsForUserDefinedAttr(attphysnum))
     			ereport(ERROR,
     					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
     					 errmsg("logical replication target relation \"%s.%s\" uses "
     							"system columns in REPLICA IDENTITY index",
     							remoterel->nspname, remoterel->relname)));
     
    -		attnum = AttrNumberGetAttrOffset(attnum);
    +		attphysnum = AttrNumberGetAttrOffset(attphysnum);
     
    -		if (entry->attrmap->attnums[attnum] < 0 ||
    -			!bms_is_member(entry->attrmap->attnums[attnum], remoterel->attkeys))
    +		if (entry->attrmap->attnums[attphysnum] < 0 ||
    +			!bms_is_member(entry->attrmap->attnums[attphysnum], remoterel->attkeys))
     		{
     			entry->updatable = false;
     			break;
    @@ -410,7 +410,7 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode)
     		missingatts = bms_add_range(NULL, 0, remoterel->natts - 1);
     		for (i = 0; i < desc->natts; i++)
     		{
    -			int			attnum;
    +			int			attphysnum;
     			Form_pg_attribute attr = TupleDescAttr(desc, i);
     
     			if (attr->attisdropped || attr->attgenerated)
    @@ -419,12 +419,12 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode)
     				continue;
     			}
     
    -			attnum = logicalrep_rel_att_by_name(remoterel,
    +			attphysnum = logicalrep_rel_att_by_name(remoterel,
     												NameStr(attr->attname));
     
    -			entry->attrmap->attnums[i] = attnum;
    -			if (attnum >= 0)
    -				missingatts = bms_del_member(missingatts, attnum);
    +			entry->attrmap->attnums[i] = attphysnum;
    +			if (attphysnum >= 0)
    +				missingatts = bms_del_member(missingatts, attphysnum);
     		}
     
     		logicalrep_report_missing_attrs(remoterel, missingatts);
    diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
    index 8da5f9089c..2dc47f8e02 100644
    --- a/src/backend/replication/logical/reorderbuffer.c
    +++ b/src/backend/replication/logical/reorderbuffer.c
    @@ -4668,7 +4668,7 @@ ReorderBufferToastReplace(ReorderBuffer *rb, ReorderBufferTXN *txn,
     		Size		data_done = 0;
     
     		/* system columns aren't toasted */
    -		if (attr->attnum < 0)
    +		if (attr->attphysnum < 0)
     			continue;
     
     		if (attr->attisdropped)
    diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c
    index 670c6fcada..ed527173fa 100644
    --- a/src/backend/replication/logical/tablesync.c
    +++ b/src/backend/replication/logical/tablesync.c
    @@ -852,17 +852,17 @@ fetch_remote_table_info(char *nspname, char *relname,
     	 */
     	resetStringInfo(&cmd);
     	appendStringInfo(&cmd,
    -					 "SELECT a.attnum,"
    +					 "SELECT a.attphysnum,"
     					 "       a.attname,"
     					 "       a.atttypid,"
    -					 "       a.attnum = ANY(i.indkey)"
    +					 "       a.attphysnum = ANY(i.indkey)"
     					 "  FROM pg_catalog.pg_attribute a"
     					 "  LEFT JOIN pg_catalog.pg_index i"
     					 "       ON (i.indexrelid = pg_get_replica_identity_index(%u))"
    -					 " WHERE a.attnum > 0::pg_catalog.int2"
    +					 " WHERE a.attphysnum > 0::pg_catalog.int2"
     					 "   AND NOT a.attisdropped %s"
     					 "   AND a.attrelid = %u"
    -					 " ORDER BY a.attnum",
    +					 " ORDER BY a.attphysnum",
     					 lrel->remoteid,
     					 (walrcv_server_version(LogRepWorkerWalRcvConn) >= 120000 ?
     					  "AND a.attgenerated = ''" : ""),
    @@ -890,13 +890,13 @@ fetch_remote_table_info(char *nspname, char *relname,
     	while (tuplestore_gettupleslot(res->tuplestore, true, false, slot))
     	{
     		char	   *rel_colname;
    -		AttrNumber	attnum;
    +		AttrNumber	attphysnum;
     
    -		attnum = DatumGetInt16(slot_getattr(slot, 1, &isnull));
    +		attphysnum = DatumGetInt16(slot_getattr(slot, 1, &isnull));
     		Assert(!isnull);
     
     		/* If the column is not in the column list, skip it. */
    -		if (included_cols != NULL && !bms_is_member(attnum, included_cols))
    +		if (included_cols != NULL && !bms_is_member(attphysnum, included_cols))
     		{
     			ExecClearTuple(slot);
     			continue;
    diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
    index 38e3b1c1b3..89da19e43f 100644
    --- a/src/backend/replication/logical/worker.c
    +++ b/src/backend/replication/logical/worker.c
    @@ -562,7 +562,7 @@ slot_fill_defaults(LogicalRepRelMapEntry *rel, EState *estate,
     	TupleDesc	desc = RelationGetDescr(rel->localrel);
     	int			num_phys_attrs = desc->natts;
     	int			i;
    -	int			attnum,
    +	int			attphysnum,
     				num_defaults = 0;
     	int		   *defmap;
     	ExprState **defexprs;
    @@ -578,17 +578,17 @@ slot_fill_defaults(LogicalRepRelMapEntry *rel, EState *estate,
     	defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *));
     
     	Assert(rel->attrmap->maplen == num_phys_attrs);
    -	for (attnum = 0; attnum < num_phys_attrs; attnum++)
    +	for (attphysnum = 0; attphysnum < num_phys_attrs; attphysnum++)
     	{
     		Expr	   *defexpr;
     
    -		if (TupleDescAttr(desc, attnum)->attisdropped || TupleDescAttr(desc, attnum)->attgenerated)
    +		if (TupleDescAttr(desc, attphysnum)->attisdropped || TupleDescAttr(desc, attphysnum)->attgenerated)
     			continue;
     
    -		if (rel->attrmap->attnums[attnum] >= 0)
    +		if (rel->attrmap->attnums[attphysnum] >= 0)
     			continue;
     
    -		defexpr = (Expr *) build_column_default(rel->localrel, attnum + 1);
    +		defexpr = (Expr *) build_column_default(rel->localrel, attphysnum + 1);
     
     		if (defexpr != NULL)
     		{
    @@ -597,7 +597,7 @@ slot_fill_defaults(LogicalRepRelMapEntry *rel, EState *estate,
     
     			/* Initialize executable expression in copycontext */
     			defexprs[num_defaults] = ExecInitExpr(defexpr, NULL);
    -			defmap[num_defaults] = attnum;
    +			defmap[num_defaults] = attphysnum;
     			num_defaults++;
     		}
     	}
    @@ -634,7 +634,7 @@ slot_store_data(TupleTableSlot *slot, LogicalRepRelMapEntry *rel,
     
     			Assert(remoteattnum < tupleData->ncols);
     
    -			/* Set attnum for error callback */
    +			/* Set attphysnum for error callback */
     			apply_error_callback_arg.remote_attnum = remoteattnum;
     
     			if (tupleData->colstatus[remoteattnum] == LOGICALREP_COLUMN_TEXT)
    @@ -683,7 +683,7 @@ slot_store_data(TupleTableSlot *slot, LogicalRepRelMapEntry *rel,
     				slot->tts_isnull[i] = true;
     			}
     
    -			/* Reset attnum for error callback */
    +			/* Reset attphysnum for error callback */
     			apply_error_callback_arg.remote_attnum = -1;
     		}
     		else
    @@ -749,7 +749,7 @@ slot_modify_data(TupleTableSlot *slot, TupleTableSlot *srcslot,
     		{
     			StringInfo	colvalue = &tupleData->colvalues[remoteattnum];
     
    -			/* Set attnum for error callback */
    +			/* Set attphysnum for error callback */
     			apply_error_callback_arg.remote_attnum = remoteattnum;
     
     			if (tupleData->colstatus[remoteattnum] == LOGICALREP_COLUMN_TEXT)
    @@ -794,7 +794,7 @@ slot_modify_data(TupleTableSlot *slot, TupleTableSlot *srcslot,
     				slot->tts_isnull[i] = true;
     			}
     
    -			/* Reset attnum for error callback */
    +			/* Reset attphysnum for error callback */
     			apply_error_callback_arg.remote_attnum = -1;
     		}
     	}
    diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
    index 8deae57143..caa4b4e9e2 100644
    --- a/src/backend/replication/pgoutput/pgoutput.c
    +++ b/src/backend/replication/pgoutput/pgoutput.c
    @@ -737,7 +737,7 @@ send_relation_and_attrs(Relation relation, TransactionId xid,
     			continue;
     
     		/* Skip this attribute if it's not present in the column list */
    -		if (columns != NULL && !bms_is_member(att->attnum, columns))
    +		if (columns != NULL && !bms_is_member(att->attphysnum, columns))
     			continue;
     
     		OutputPluginPrepareWrite(ctx, false);
    diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
    index e42671722a..6b6430f941 100644
    --- a/src/backend/replication/walsender.c
    +++ b/src/backend/replication/walsender.c
    @@ -602,7 +602,7 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd)
     	/* first field */
     	pq_sendstring(&buf, "filename");	/* col name */
     	pq_sendint32(&buf, 0);		/* table oid */
    -	pq_sendint16(&buf, 0);		/* attnum */
    +	pq_sendint16(&buf, 0);		/* attphysnum */
     	pq_sendint32(&buf, TEXTOID);	/* type oid */
     	pq_sendint16(&buf, -1);		/* typlen */
     	pq_sendint32(&buf, 0);		/* typmod */
    @@ -611,7 +611,7 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd)
     	/* second field */
     	pq_sendstring(&buf, "content"); /* col name */
     	pq_sendint32(&buf, 0);		/* table oid */
    -	pq_sendint16(&buf, 0);		/* attnum */
    +	pq_sendint16(&buf, 0);		/* attphysnum */
     	pq_sendint32(&buf, TEXTOID);	/* type oid */
     	pq_sendint16(&buf, -1);		/* typlen */
     	pq_sendint32(&buf, 0);		/* typmod */
    diff --git a/src/backend/statistics/dependencies.c b/src/backend/statistics/dependencies.c
    index c1c27e67d4..db14e35c86 100644
    --- a/src/backend/statistics/dependencies.c
    +++ b/src/backend/statistics/dependencies.c
    @@ -76,7 +76,7 @@ static double dependency_degree(StatsBuildData *data, int k, AttrNumber *depende
     static bool dependency_is_fully_matched(MVDependency *dependency,
     										Bitmapset *attnums);
     static bool dependency_is_compatible_clause(Node *clause, Index relid,
    -											AttrNumber *attnum);
    +											AttrNumber *attphysnum);
     static bool dependency_is_compatible_expression(Node *clause, Index relid,
     												List *statlist, Node **expr);
     static MVDependency *find_strongest_dependency(MVDependencies **dependencies,
    @@ -604,9 +604,9 @@ dependency_is_fully_matched(MVDependency *dependency, Bitmapset *attnums)
     	 */
     	for (j = 0; j < dependency->nattributes; j++)
     	{
    -		int			attnum = dependency->attributes[j];
    +		int			attphysnum = dependency->attributes[j];
     
    -		if (!bms_is_member(attnum, attnums))
    +		if (!bms_is_member(attphysnum, attnums))
     			return false;
     	}
     
    @@ -737,10 +737,10 @@ pg_dependencies_send(PG_FUNCTION_ARGS)
      * Only clauses that have the form of equality to a pseudoconstant, or can be
      * interpreted that way, are currently accepted.  Furthermore the variable
      * part of the clause must be a simple Var belonging to the specified
    - * relation, whose attribute number we return in *attnum on success.
    + * relation, whose attribute number we return in *attphysnum on success.
      */
     static bool
    -dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum)
    +dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attphysnum)
     {
     	Var		   *var;
     	Node	   *clause_expr;
    @@ -839,7 +839,7 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum)
     		ListCell   *lc;
     
     		/* start with no attribute number */
    -		*attnum = InvalidAttrNumber;
    +		*attphysnum = InvalidAttrNumber;
     
     		foreach(lc, bool_expr->args)
     		{
    @@ -853,11 +853,11 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum)
     												 relid, &clause_attnum))
     				return false;
     
    -			if (*attnum == InvalidAttrNumber)
    -				*attnum = clause_attnum;
    +			if (*attphysnum == InvalidAttrNumber)
    +				*attphysnum = clause_attnum;
     
    -			/* ensure all the variables are the same (same attnum) */
    -			if (*attnum != clause_attnum)
    +			/* ensure all the variables are the same (same attphysnum) */
    +			if (*attphysnum != clause_attnum)
     				return false;
     		}
     
    @@ -907,7 +907,7 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum)
     	if (!AttrNumberIsForUserDefinedAttr(var->varattno))
     		return false;
     
    -	*attnum = var->varattno;
    +	*attphysnum = var->varattno;
     	return true;
     }
     
    @@ -1041,9 +1041,9 @@ clauselist_apply_dependencies(PlannerInfo *root, List *clauses,
     	{
     		for (j = 0; j < dependencies[i]->nattributes; j++)
     		{
    -			AttrNumber	attnum = dependencies[i]->attributes[j];
    +			AttrNumber	attphysnum = dependencies[i]->attributes[j];
     
    -			attnums = bms_add_member(attnums, attnum);
    +			attnums = bms_add_member(attnums, attphysnum);
     		}
     	}
     
    @@ -1106,7 +1106,7 @@ clauselist_apply_dependencies(PlannerInfo *root, List *clauses,
     	for (i = ndependencies - 1; i >= 0; i--)
     	{
     		MVDependency *dependency = dependencies[i];
    -		AttrNumber	attnum;
    +		AttrNumber	attphysnum;
     		Selectivity s2;
     		double		f;
     
    @@ -1114,14 +1114,14 @@ clauselist_apply_dependencies(PlannerInfo *root, List *clauses,
     		s1 = 1.0;
     		for (j = 0; j < dependency->nattributes - 1; j++)
     		{
    -			attnum = dependency->attributes[j];
    -			attidx = bms_member_index(attnums, attnum);
    +			attphysnum = dependency->attributes[j];
    +			attidx = bms_member_index(attnums, attphysnum);
     			s1 *= attr_sel[attidx];
     		}
     
     		/* Original selectivity of the implied attribute */
    -		attnum = dependency->attributes[j];
    -		attidx = bms_member_index(attnums, attnum);
    +		attphysnum = dependency->attributes[j];
    +		attidx = bms_member_index(attnums, attphysnum);
     		s2 = attr_sel[attidx];
     
     		/*
    @@ -1454,7 +1454,7 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     	foreach(l, clauses)
     	{
     		Node	   *clause = (Node *) lfirst(l);
    -		AttrNumber	attnum;
    +		AttrNumber	attphysnum;
     		Node	   *expr = NULL;
     
     		/* ignore clause by default */
    @@ -1464,19 +1464,19 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     		{
     			/*
     			 * If it's a simple column reference, just extract the attnum. If
    -			 * it's an expression, assign a negative attnum as if it was a
    +			 * it's an expression, assign a negative attphysnum as if it was a
     			 * system attribute.
     			 */
    -			if (dependency_is_compatible_clause(clause, rel->relid, &attnum))
    +			if (dependency_is_compatible_clause(clause, rel->relid, &attphysnum))
     			{
    -				list_attnums[listidx] = attnum;
    +				list_attnums[listidx] = attphysnum;
     			}
     			else if (dependency_is_compatible_expression(clause, rel->relid,
     														 rel->statlist,
     														 &expr))
     			{
    -				/* special attnum assigned to this expression */
    -				attnum = InvalidAttrNumber;
    +				/* special attphysnum assigned to this expression */
    +				attphysnum = InvalidAttrNumber;
     
     				Assert(expr != NULL);
     
    @@ -1486,22 +1486,22 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     					if (equal(unique_exprs[i], expr))
     					{
     						/* negative attribute number to expression */
    -						attnum = -(i + 1);
    +						attphysnum = -(i + 1);
     						break;
     					}
     				}
     
     				/* not found in the list, so add it */
    -				if (attnum == InvalidAttrNumber)
    +				if (attphysnum == InvalidAttrNumber)
     				{
     					unique_exprs[unique_exprs_cnt++] = expr;
     
     					/* after incrementing the value, to get -1, -2, ... */
    -					attnum = (-unique_exprs_cnt);
    +					attphysnum = (-unique_exprs_cnt);
     				}
     
    -				/* remember which attnum was assigned to this clause */
    -				list_attnums[listidx] = attnum;
    +				/* remember which attphysnum was assigned to this clause */
    +				list_attnums[listidx] = attphysnum;
     			}
     		}
     
    @@ -1526,39 +1526,39 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     	 */
     	for (i = 0; i < list_length(clauses); i++)
     	{
    -		AttrNumber	attnum;
    +		AttrNumber	attphysnum;
     
     		/* ignore incompatible or already estimated clauses */
     		if (list_attnums[i] == InvalidAttrNumber)
     			continue;
     
    -		/* make sure the attnum is in the expected range */
    +		/* make sure the attphysnum is in the expected range */
     		Assert(list_attnums[i] >= (-unique_exprs_cnt));
     		Assert(list_attnums[i] <= MaxHeapAttributeNumber);
     
    -		/* make sure the attnum is positive (valid AttrNumber) */
    -		attnum = list_attnums[i] + attnum_offset;
    +		/* make sure the attphysnum is positive (valid AttrNumber) */
    +		attphysnum = list_attnums[i] + attnum_offset;
     
     		/*
     		 * Either it's a regular attribute, or it's an expression, in which
     		 * case we must not have seen it before (expressions are unique).
     		 *
     		 * XXX Check whether it's a regular attribute has to be done using the
    -		 * original attnum, while the second check has to use the value with
    +		 * original attphysnum, while the second check has to use the value with
     		 * an offset.
     		 */
     		Assert(AttrNumberIsForUserDefinedAttr(list_attnums[i]) ||
    -			   !bms_is_member(attnum, clauses_attnums));
    +			   !bms_is_member(attphysnum, clauses_attnums));
     
     		/*
    -		 * Remember the offset attnum, both for attributes and expressions.
    +		 * Remember the offset attphysnum, both for attributes and expressions.
     		 * We'll pass list_attnums to clauselist_apply_dependencies, which
     		 * uses it to identify clauses in a bitmap. We could also pass the
     		 * offset, but this is more convenient.
     		 */
    -		list_attnums[i] = attnum;
    +		list_attnums[i] = attphysnum;
     
    -		clauses_attnums = bms_add_member(clauses_attnums, attnum);
    +		clauses_attnums = bms_add_member(clauses_attnums, attphysnum);
     	}
     
     	/*
    @@ -1606,7 +1606,7 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     			continue;
     
     		/*
    -		 * Count matching attributes - we have to undo the attnum offsets. The
    +		 * Count matching attributes - we have to undo the attphysnum offsets. The
     		 * input attribute numbers are not offset (expressions are not
     		 * included in stat->keys, so it's not necessary). But we need to
     		 * offset it before checking against clauses_attnums.
    @@ -1615,16 +1615,16 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     		k = -1;
     		while ((k = bms_next_member(stat->keys, k)) >= 0)
     		{
    -			AttrNumber	attnum = (AttrNumber) k;
    +			AttrNumber	attphysnum = (AttrNumber) k;
     
     			/* skip expressions */
    -			if (!AttrNumberIsForUserDefinedAttr(attnum))
    +			if (!AttrNumberIsForUserDefinedAttr(attphysnum))
     				continue;
     
     			/* apply the same offset as above */
    -			attnum += attnum_offset;
    +			attphysnum += attnum_offset;
     
    -			if (bms_is_member(attnum, clauses_attnums))
    +			if (bms_is_member(attphysnum, clauses_attnums))
     				nmatched++;
     		}
     
    @@ -1695,20 +1695,20 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     					Node	   *expr;
     					int			k;
     					AttrNumber	unique_attnum = InvalidAttrNumber;
    -					AttrNumber	attnum;
    +					AttrNumber	attphysnum;
     
     					/* undo the per-statistics offset */
    -					attnum = dep->attributes[j];
    +					attphysnum = dep->attributes[j];
     
     					/*
     					 * For regular attributes we can simply check if it
     					 * matches any clause. If there's no matching clause, we
    -					 * can just ignore it. We need to offset the attnum
    +					 * can just ignore it. We need to offset the attphysnum
     					 * though.
     					 */
    -					if (AttrNumberIsForUserDefinedAttr(attnum))
    +					if (AttrNumberIsForUserDefinedAttr(attphysnum))
     					{
    -						dep->attributes[j] = attnum + attnum_offset;
    +						dep->attributes[j] = attphysnum + attnum_offset;
     
     						if (!bms_is_member(dep->attributes[j], clauses_attnums))
     						{
    @@ -1720,20 +1720,20 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     					}
     
     					/*
    -					 * the attnum should be a valid system attnum (-1, -2,
    +					 * the attphysnum should be a valid system attphysnum (-1, -2,
     					 * ...)
     					 */
    -					Assert(AttributeNumberIsValid(attnum));
    +					Assert(AttributeNumberIsValid(attphysnum));
     
     					/*
     					 * For expressions, we need to do two translations. First
    -					 * we have to translate the negative attnum to index in
    +					 * we have to translate the negative attphysnum to index in
     					 * the list of expressions (in the statistics object).
     					 * Then we need to see if there's a matching clause. The
    -					 * index of the unique expression determines the attnum
    +					 * index of the unique expression determines the attphysnum
     					 * (and we offset it).
     					 */
    -					idx = -(1 + attnum);
    +					idx = -(1 + attphysnum);
     
     					/* Is the expression index is valid? */
     					Assert((idx >= 0) && (idx < list_length(stat->exprs)));
    @@ -1744,7 +1744,7 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     					for (k = 0; k < unique_exprs_cnt; k++)
     					{
     						/*
    -						 * found a matching unique expression, use the attnum
    +						 * found a matching unique expression, use the attphysnum
     						 * (derived from index of the unique expression)
     						 */
     						if (equal(unique_exprs[k], expr))
    @@ -1765,7 +1765,7 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     						break;
     					}
     
    -					/* otherwise remap it to the new attnum */
    +					/* otherwise remap it to the new attphysnum */
     					dep->attributes[j] = unique_attnum;
     				}
     
    @@ -1816,7 +1816,7 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     	while (true)
     	{
     		MVDependency *dependency;
    -		AttrNumber	attnum;
    +		AttrNumber	attphysnum;
     
     		/* the widest/strongest dependency, fully matched by clauses */
     		dependency = find_strongest_dependency(func_dependencies,
    @@ -1828,8 +1828,8 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
     		dependencies[ndependencies++] = dependency;
     
     		/* Ignore dependencies using this implied attribute in later loops */
    -		attnum = dependency->attributes[dependency->nattributes - 1];
    -		clauses_attnums = bms_del_member(clauses_attnums, attnum);
    +		attphysnum = dependency->attributes[dependency->nattributes - 1];
    +		clauses_attnums = bms_del_member(clauses_attnums, attphysnum);
     	}
     
     	/*
    diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
    index ca48395d5c..b11db27812 100644
    --- a/src/backend/statistics/extended_stats.c
    +++ b/src/backend/statistics/extended_stats.c
    @@ -391,31 +391,31 @@ statext_compute_stattarget(int stattarget, int nattrs, VacAttrStats **stats)
     bool
     statext_is_kind_built(HeapTuple htup, char type)
     {
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     
     	switch (type)
     	{
     		case STATS_EXT_NDISTINCT:
    -			attnum = Anum_pg_statistic_ext_data_stxdndistinct;
    +			attphysnum = Anum_pg_statistic_ext_data_stxdndistinct;
     			break;
     
     		case STATS_EXT_DEPENDENCIES:
    -			attnum = Anum_pg_statistic_ext_data_stxddependencies;
    +			attphysnum = Anum_pg_statistic_ext_data_stxddependencies;
     			break;
     
     		case STATS_EXT_MCV:
    -			attnum = Anum_pg_statistic_ext_data_stxdmcv;
    +			attphysnum = Anum_pg_statistic_ext_data_stxdmcv;
     			break;
     
     		case STATS_EXT_EXPRESSIONS:
    -			attnum = Anum_pg_statistic_ext_data_stxdexpr;
    +			attphysnum = Anum_pg_statistic_ext_data_stxdexpr;
     			break;
     
     		default:
     			elog(ERROR, "unexpected statistics type requested: %d", type);
     	}
     
    -	return !heap_attisnull(htup, attnum, NULL);
    +	return !heap_attisnull(htup, attphysnum, NULL);
     }
     
     /*
    @@ -655,7 +655,7 @@ examine_expression(Node *expr, int stattarget)
     
     	/* initialize some basic fields */
     	stats->attr->attrelid = InvalidOid;
    -	stats->attr->attnum = InvalidAttrNumber;
    +	stats->attr->attphysnum = InvalidAttrNumber;
     	stats->attr->atttypid = stats->attrtypid;
     
     	typtuple = SearchSysCacheCopy1(TYPEOID,
    @@ -722,7 +722,7 @@ lookup_var_attr_stats(Relation rel, Bitmapset *attrs, List *exprs,
     
     	stats = (VacAttrStats **) palloc(natts * sizeof(VacAttrStats *));
     
    -	/* lookup VacAttrStats info for the requested columns (same attnum) */
    +	/* lookup VacAttrStats info for the requested columns (same attphysnum) */
     	while ((x = bms_next_member(attrs, x)) >= 0)
     	{
     		int			j;
    @@ -979,7 +979,7 @@ build_attnums_array(Bitmapset *attrs, int nexprs, int *numattrs)
     	j = -1;
     	while ((j = bms_next_member(attrs, j)) >= 0)
     	{
    -		int			attnum = (j - nexprs);
    +		int			attphysnum = (j - nexprs);
     
     		/*
     		 * Make sure the bitmap contains only user-defined attributes. As
    @@ -987,11 +987,11 @@ build_attnums_array(Bitmapset *attrs, int nexprs, int *numattrs)
     		 * ways. Firstly, the bitmap might contain 0 as a member, and secondly
     		 * the integer value might be larger than MaxAttrNumber.
     		 */
    -		Assert(AttributeNumberIsValid(attnum));
    -		Assert(attnum <= MaxAttrNumber);
    -		Assert(attnum >= (-nexprs));
    +		Assert(AttributeNumberIsValid(attphysnum));
    +		Assert(attphysnum <= MaxAttrNumber);
    +		Assert(attphysnum >= (-nexprs));
     
    -		attnums[i++] = (AttrNumber) attnum;
    +		attnums[i++] = (AttrNumber) attphysnum;
     
     		/* protect against overflows */
     		Assert(i <= num);
    @@ -1070,14 +1070,14 @@ build_sorted_items(StatsBuildData *data, int *nitems,
     			Datum		value;
     			bool		isnull;
     			int			attlen;
    -			AttrNumber	attnum = attnums[j];
    +			AttrNumber	attphysnum = attnums[j];
     
     			int			idx;
     
    -			/* match attnum to the pre-calculated data */
    +			/* match attphysnum to the pre-calculated data */
     			for (idx = 0; idx < data->nattnums; idx++)
     			{
    -				if (attnum == data->attnums[idx])
    +				if (attphysnum == data->attnums[idx])
     					break;
     			}
     
    @@ -1635,11 +1635,11 @@ statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid,
     		else
     		{
     			/* Check the columns referenced by the clause */
    -			int			attnum = -1;
    +			int			attphysnum = -1;
     
    -			while ((attnum = bms_next_member(clause_attnums, attnum)) >= 0)
    +			while ((attphysnum = bms_next_member(clause_attnums, attphysnum)) >= 0)
     			{
    -				if (pg_attribute_aclcheck(rte->relid, attnum, userid,
    +				if (pg_attribute_aclcheck(rte->relid, attphysnum, userid,
     										  ACL_SELECT) != ACLCHECK_OK)
     					return false;
     			}
    @@ -2186,7 +2186,7 @@ compute_expr_stats(Relation onerel, double totalrows,
     		{
     			AttributeOpts *aopt =
     			get_attribute_options(stats->attr->attrelid,
    -								  stats->attr->attnum);
    +								  stats->attr->attphysnum);
     
     			stats->exprvals = exprvals;
     			stats->exprnulls = exprnulls;
    diff --git a/src/backend/statistics/mvdistinct.c b/src/backend/statistics/mvdistinct.c
    index 6ade5eff78..e8e8682c8a 100644
    --- a/src/backend/statistics/mvdistinct.c
    +++ b/src/backend/statistics/mvdistinct.c
    @@ -373,9 +373,9 @@ pg_ndistinct_out(PG_FUNCTION_ARGS)
     
     		for (j = 0; j < item.nattributes; j++)
     		{
    -			AttrNumber	attnum = item.attributes[j];
    +			AttrNumber	attphysnum = item.attributes[j];
     
    -			appendStringInfo(&str, "%s%d", (j == 0) ? "\"" : ", ", attnum);
    +			appendStringInfo(&str, "%s%d", (j == 0) ? "\"" : ", ", attphysnum);
     		}
     		appendStringInfo(&str, "\": %d", (int) item.ndistinct);
     	}
    diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
    index 772c04155c..0659109257 100644
    --- a/src/backend/utils/adt/acl.c
    +++ b/src/backend/utils/adt/acl.c
    @@ -2444,13 +2444,13 @@ has_any_column_privilege_id_id(PG_FUNCTION_ARGS)
      * has_column_privilege variants
      *		These are all named "has_column_privilege" at the SQL level.
      *		They take various combinations of relation name, relation OID,
    - *		column name, column attnum, user name, user OID, or
    + *		column name, column attphysnum, user name, user OID, or
      *		implicit user = current_user.
      *
      *		The result is a boolean value: true if user has the indicated
      *		privilege, false if not.  The variants that take a relation OID
      *		return NULL (rather than throwing an error) if that relation OID
    - *		doesn't exist.  Likewise, the variants that take an integer attnum
    + *		doesn't exist.  Likewise, the variants that take an integer attphysnum
      *		return NULL (rather than throwing an error) if there is no such
      *		pg_attribute entry.  All variants return NULL if an attisdropped
      *		column is selected.  These rules are meant to avoid unnecessary
    @@ -2464,7 +2464,7 @@ has_any_column_privilege_id_id(PG_FUNCTION_ARGS)
      * Returns 1 if have the privilege, 0 if not, -1 if dropped column/table.
      */
     static int
    -column_privilege_check(Oid tableoid, AttrNumber attnum,
    +column_privilege_check(Oid tableoid, AttrNumber attphysnum,
     					   Oid roleid, AclMode mode)
     {
     	AclResult	aclresult;
    @@ -2473,7 +2473,7 @@ column_privilege_check(Oid tableoid, AttrNumber attnum,
     	/*
     	 * If convert_column_name failed, we can just return -1 immediately.
     	 */
    -	if (attnum == InvalidAttrNumber)
    +	if (attphysnum == InvalidAttrNumber)
     		return -1;
     
     	/*
    @@ -2481,7 +2481,7 @@ column_privilege_check(Oid tableoid, AttrNumber attnum,
     	 * on whether the column even exists, so we need to do it before checking
     	 * table-level privilege.
     	 */
    -	aclresult = pg_attribute_aclcheck_ext(tableoid, attnum, roleid,
    +	aclresult = pg_attribute_aclcheck_ext(tableoid, attphysnum, roleid,
     										  mode, &is_missing);
     	if (aclresult == ACLCHECK_OK)
     		return 1;
    @@ -2530,7 +2530,7 @@ has_column_privilege_name_name_name(PG_FUNCTION_ARGS)
     /*
      * has_column_privilege_name_name_attnum
      *		Check user privileges on a column given
    - *		name username, text tablename, int attnum, and text priv name.
    + *		name username, text tablename, int attphysnum, and text priv name.
      */
     Datum
     has_column_privilege_name_name_attnum(PG_FUNCTION_ARGS)
    @@ -2584,7 +2584,7 @@ has_column_privilege_name_id_name(PG_FUNCTION_ARGS)
     /*
      * has_column_privilege_name_id_attnum
      *		Check user privileges on a column given
    - *		name username, table oid, int attnum, and text priv name.
    + *		name username, table oid, int attphysnum, and text priv name.
      */
     Datum
     has_column_privilege_name_id_attnum(PG_FUNCTION_ARGS)
    @@ -2636,7 +2636,7 @@ has_column_privilege_id_name_name(PG_FUNCTION_ARGS)
     /*
      * has_column_privilege_id_name_attnum
      *		Check user privileges on a column given
    - *		oid roleid, text tablename, int attnum, and text priv name.
    + *		oid roleid, text tablename, int attphysnum, and text priv name.
      */
     Datum
     has_column_privilege_id_name_attnum(PG_FUNCTION_ARGS)
    @@ -2686,7 +2686,7 @@ has_column_privilege_id_id_name(PG_FUNCTION_ARGS)
     /*
      * has_column_privilege_id_id_attnum
      *		Check user privileges on a column given
    - *		oid roleid, table oid, int attnum, and text priv name.
    + *		oid roleid, table oid, int attphysnum, and text priv name.
      */
     Datum
     has_column_privilege_id_id_attnum(PG_FUNCTION_ARGS)
    @@ -2738,7 +2738,7 @@ has_column_privilege_name_name(PG_FUNCTION_ARGS)
     /*
      * has_column_privilege_name_attnum
      *		Check user privileges on a column given
    - *		text tablename, int attnum, and text priv name.
    + *		text tablename, int attphysnum, and text priv name.
      *		current_user is assumed
      */
     Datum
    @@ -2792,7 +2792,7 @@ has_column_privilege_id_name(PG_FUNCTION_ARGS)
     /*
      * has_column_privilege_id_attnum
      *		Check user privileges on a column given
    - *		table oid, int attnum, and text priv name.
    + *		table oid, int attphysnum, and text priv name.
      *		current_user is assumed
      */
     Datum
    @@ -2828,12 +2828,12 @@ convert_column_name(Oid tableoid, text *column)
     {
     	char	   *colname;
     	HeapTuple	attTuple;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     
     	colname = text_to_cstring(column);
     
     	/*
    -	 * We don't use get_attnum() here because it will report that dropped
    +	 * We don't use get_attphysnum() here because it will report that dropped
     	 * columns don't exist.  We need to treat dropped columns differently from
     	 * nonexistent columns.
     	 */
    @@ -2847,9 +2847,9 @@ convert_column_name(Oid tableoid, text *column)
     		attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple);
     		/* We want to return NULL for dropped columns */
     		if (attributeForm->attisdropped)
    -			attnum = InvalidAttrNumber;
    +			attphysnum = InvalidAttrNumber;
     		else
    -			attnum = attributeForm->attnum;
    +			attphysnum = attributeForm->attphysnum;
     		ReleaseSysCache(attTuple);
     	}
     	else
    @@ -2870,11 +2870,11 @@ convert_column_name(Oid tableoid, text *column)
     							colname, tablename)));
     		}
     		/* tableoid doesn't exist, so act like attisdropped case */
    -		attnum = InvalidAttrNumber;
    +		attphysnum = InvalidAttrNumber;
     	}
     
     	pfree(colname);
    -	return attnum;
    +	return attphysnum;
     }
     
     /*
    diff --git a/src/backend/utils/adt/expandedrecord.c b/src/backend/utils/adt/expandedrecord.c
    index 3b3e0a9106..18951a40ce 100644
    --- a/src/backend/utils/adt/expandedrecord.c
    +++ b/src/backend/utils/adt/expandedrecord.c
    @@ -1031,7 +1031,7 @@ expanded_record_lookup_field(ExpandedRecordHeader *erh, const char *fieldname,
     		if (namestrcmp(&attr->attname, fieldname) == 0 &&
     			!attr->attisdropped)
     		{
    -			finfo->fnumber = attr->attnum;
    +			finfo->fnumber = attr->attphysnum;
     			finfo->ftypeid = attr->atttypid;
     			finfo->ftypmod = attr->atttypmod;
     			finfo->fcollation = attr->attcollation;
    @@ -1043,7 +1043,7 @@ expanded_record_lookup_field(ExpandedRecordHeader *erh, const char *fieldname,
     	sysattr = SystemAttributeByName(fieldname);
     	if (sysattr != NULL)
     	{
    -		finfo->fnumber = sysattr->attnum;
    +		finfo->fnumber = sysattr->attphysnum;
     		finfo->ftypeid = sysattr->atttypid;
     		finfo->ftypmod = sysattr->atttypmod;
     		finfo->fcollation = sysattr->attcollation;
    diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
    index 89690be2ed..5ad1cdc905 100644
    --- a/src/backend/utils/adt/misc.c
    +++ b/src/backend/utils/adt/misc.c
    @@ -636,13 +636,13 @@ Datum
     pg_column_is_updatable(PG_FUNCTION_ARGS)
     {
     	Oid			reloid = PG_GETARG_OID(0);
    -	AttrNumber	attnum = PG_GETARG_INT16(1);
    -	AttrNumber	col = attnum - FirstLowInvalidHeapAttributeNumber;
    +	AttrNumber	attphysnum = PG_GETARG_INT16(1);
    +	AttrNumber	col = attphysnum - FirstLowInvalidHeapAttributeNumber;
     	bool		include_triggers = PG_GETARG_BOOL(2);
     	int			events;
     
     	/* System columns are never updatable */
    -	if (attnum <= 0)
    +	if (attphysnum <= 0)
     		PG_RETURN_BOOL(false);
     
     	events = relation_is_updatable(reloid, NIL, include_triggers,
    diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
    index 51b3fdc9a0..cb28faa420 100644
    --- a/src/backend/utils/adt/ri_triggers.c
    +++ b/src/backend/utils/adt/ri_triggers.c
    @@ -85,9 +85,9 @@
     #define MAX_QUOTED_NAME_LEN  (NAMEDATALEN*2+3)
     #define MAX_QUOTED_REL_NAME_LEN  (MAX_QUOTED_NAME_LEN*2)
     
    -#define RIAttName(rel, attnum)	NameStr(*attnumAttName(rel, attnum))
    -#define RIAttType(rel, attnum)	attnumTypeId(rel, attnum)
    -#define RIAttCollation(rel, attnum) attnumCollationId(rel, attnum)
    +#define RIAttName(rel, attphysnum)	NameStr(*attnumAttName(rel, attphysnum))
    +#define RIAttType(rel, attphysnum)	attnumTypeId(rel, attphysnum)
    +#define RIAttCollation(rel, attphysnum) attnumCollationId(rel, attphysnum)
     
     #define RI_TRIGTYPE_INSERT 1
     #define RI_TRIGTYPE_UPDATE 2
    diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
    index c3937a60fd..837dc6b20d 100644
    --- a/src/backend/utils/adt/ruleutils.c
    +++ b/src/backend/utils/adt/ruleutils.c
    @@ -1348,7 +1348,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
     	sep = "";
     	for (keyno = 0; keyno < idxrec->indnatts; keyno++)
     	{
    -		AttrNumber	attnum = idxrec->indkey.values[keyno];
    +		AttrNumber	attphysnum = idxrec->indkey.values[keyno];
     		Oid			keycoltype;
     		Oid			keycolcollation;
     
    @@ -1369,16 +1369,16 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
     			appendStringInfoString(&buf, sep);
     		sep = ", ";
     
    -		if (attnum != 0)
    +		if (attphysnum != 0)
     		{
     			/* Simple index column */
     			char	   *attname;
     			int32		keycoltypmod;
     
    -			attname = get_attname(indrelid, attnum, false);
    +			attname = get_attname(indrelid, attphysnum, false);
     			if (!colno || colno == keyno + 1)
     				appendStringInfoString(&buf, quote_identifier(attname));
    -			get_atttypetypmodcoll(indrelid, attnum,
    +			get_atttypetypmodcoll(indrelid, attphysnum,
     								  &keycoltype, &keycoltypmod,
     								  &keycolcollation);
     		}
    @@ -1744,13 +1744,13 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
     	/* decode simple column references */
     	for (colno = 0; colno < statextrec->stxkeys.dim1; colno++)
     	{
    -		AttrNumber	attnum = statextrec->stxkeys.values[colno];
    +		AttrNumber	attphysnum = statextrec->stxkeys.values[colno];
     		char	   *attname;
     
     		if (colno > 0)
     			appendStringInfoString(&buf, ", ");
     
    -		attname = get_attname(statextrec->stxrelid, attnum, false);
    +		attname = get_attname(statextrec->stxrelid, attphysnum, false);
     
     		appendStringInfoString(&buf, quote_identifier(attname));
     	}
    @@ -1990,22 +1990,22 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags,
     	sep = "";
     	for (keyno = 0; keyno < form->partnatts; keyno++)
     	{
    -		AttrNumber	attnum = form->partattrs.values[keyno];
    +		AttrNumber	attphysnum = form->partattrs.values[keyno];
     		Oid			keycoltype;
     		Oid			keycolcollation;
     		Oid			partcoll;
     
     		appendStringInfoString(&buf, sep);
     		sep = ", ";
    -		if (attnum != 0)
    +		if (attphysnum != 0)
     		{
     			/* Simple attribute reference */
     			char	   *attname;
     			int32		keycoltypmod;
     
    -			attname = get_attname(relid, attnum, false);
    +			attname = get_attname(relid, attphysnum, false);
     			appendStringInfoString(&buf, quote_identifier(attname));
    -			get_atttypetypmodcoll(relid, attnum,
    +			get_atttypetypmodcoll(relid, attphysnum,
     								  &keycoltype, &keycoltypmod,
     								  &keycolcollation);
     		}
    @@ -2798,7 +2798,7 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
     	RangeVar   *tablerv;
     	Oid			tableOid;
     	char	   *column;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	Oid			sequenceId = InvalidOid;
     	Relation	depRel;
     	ScanKeyData key[3];
    @@ -2812,8 +2812,8 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
     	/* Get the number of the column */
     	column = text_to_cstring(columnname);
     
    -	attnum = get_attnum(tableOid, column);
    -	if (attnum == InvalidAttrNumber)
    +	attphysnum = get_attphysnum(tableOid, column);
    +	if (attphysnum == InvalidAttrNumber)
     		ereport(ERROR,
     				(errcode(ERRCODE_UNDEFINED_COLUMN),
     				 errmsg("column \"%s\" of relation \"%s\" does not exist",
    @@ -2833,7 +2833,7 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
     	ScanKeyInit(&key[2],
     				Anum_pg_depend_refobjsubid,
     				BTEqualStrategyNumber, F_INT4EQ,
    -				Int32GetDatum(attnum));
    +				Int32GetDatum(attphysnum));
     
     	scan = systable_beginscan(depRel, DependReferenceIndexId, true,
     							  NULL, 3, key);
    @@ -4595,7 +4595,7 @@ set_join_column_names(deparse_namespace *dpns, RangeTblEntry *rte,
     	 * added since parse time must be inserted in the right places.  This code
     	 * must match the parser, which will order a join's columns as merged
     	 * columns first (in USING-clause order), then non-merged columns from the
    -	 * left input (in attnum order), then non-merged columns from the right
    +	 * left input (in attphysnum order), then non-merged columns from the right
     	 * input (ditto).  If one of the inputs is itself a join, its columns will
     	 * be ordered according to the same rule, which means newly-added columns
     	 * might not be at the end.  We can figure out what's what by consulting
    @@ -7118,7 +7118,7 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
     {
     	StringInfo	buf = context->buf;
     	RangeTblEntry *rte;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	int			netlevelsup;
     	deparse_namespace *dpns;
     	int			varno;
    @@ -7209,7 +7209,7 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
     		rte = rt_fetch(varno, dpns->rtable);
     		refname = (char *) list_nth(dpns->rtable_names, varno - 1);
     		colinfo = deparse_columns_fetch(varno, dpns);
    -		attnum = varattno;
    +		attphysnum = varattno;
     	}
     	else
     	{
    @@ -7230,16 +7230,16 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
     	 * we'll have set dpns->inner_plan to reference the child plan node.
     	 */
     	if ((rte->rtekind == RTE_SUBQUERY || rte->rtekind == RTE_CTE) &&
    -		attnum > list_length(rte->eref->colnames) &&
    +		attphysnum > list_length(rte->eref->colnames) &&
     		dpns->inner_plan)
     	{
     		TargetEntry *tle;
     		deparse_namespace save_dpns;
     
    -		tle = get_tle_by_resno(dpns->inner_tlist, attnum);
    +		tle = get_tle_by_resno(dpns->inner_tlist, attphysnum);
     		if (!tle)
    -			elog(ERROR, "invalid attnum %d for relation \"%s\"",
    -				 attnum, rte->eref->aliasname);
    +			elog(ERROR, "invalid attphysnum %d for relation \"%s\"",
    +				 attphysnum, rte->eref->aliasname);
     
     		Assert(netlevelsup == 0);
     		push_child_plan(dpns, dpns->inner_plan, &save_dpns);
    @@ -7274,11 +7274,11 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
     	{
     		if (rte->joinaliasvars == NIL)
     			elog(ERROR, "cannot decompile join alias var in plan tree");
    -		if (attnum > 0)
    +		if (attphysnum > 0)
     		{
     			Var		   *aliasvar;
     
    -			aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
    +			aliasvar = (Var *) list_nth(rte->joinaliasvars, attphysnum - 1);
     			/* we intentionally don't strip implicit coercions here */
     			if (aliasvar && IsA(aliasvar, Var))
     			{
    @@ -7295,23 +7295,23 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
     		Assert(refname == NULL);
     	}
     
    -	if (attnum == InvalidAttrNumber)
    +	if (attphysnum == InvalidAttrNumber)
     		attname = NULL;
    -	else if (attnum > 0)
    +	else if (attphysnum > 0)
     	{
     		/* Get column name to use from the colinfo struct */
    -		if (attnum > colinfo->num_cols)
    -			elog(ERROR, "invalid attnum %d for relation \"%s\"",
    -				 attnum, rte->eref->aliasname);
    -		attname = colinfo->colnames[attnum - 1];
    +		if (attphysnum > colinfo->num_cols)
    +			elog(ERROR, "invalid attphysnum %d for relation \"%s\"",
    +				 attphysnum, rte->eref->aliasname);
    +		attname = colinfo->colnames[attphysnum - 1];
     		if (attname == NULL)	/* dropped column? */
    -			elog(ERROR, "invalid attnum %d for relation \"%s\"",
    -				 attnum, rte->eref->aliasname);
    +			elog(ERROR, "invalid attphysnum %d for relation \"%s\"",
    +				 attphysnum, rte->eref->aliasname);
     	}
     	else
     	{
     		/* System column - name is fixed, get it from the catalog */
    -		attname = get_rte_attribute_name(rte, attnum);
    +		attname = get_rte_attribute_name(rte, attphysnum);
     	}
     
     	if (refname && (context->varprefix || attname == NULL))
    @@ -7474,7 +7474,7 @@ get_name_for_var_field(Var *var, int fieldno,
     					   int levelsup, deparse_context *context)
     {
     	RangeTblEntry *rte;
    -	AttrNumber	attnum;
    +	AttrNumber	attphysnum;
     	int			netlevelsup;
     	deparse_namespace *dpns;
     	int			varno;
    @@ -7566,7 +7566,7 @@ get_name_for_var_field(Var *var, int fieldno,
     	if (varno >= 1 && varno <= list_length(dpns->rtable))
     	{
     		rte = rt_fetch(varno, dpns->rtable);
    -		attnum = varattno;
    +		attphysnum = varattno;
     	}
     	else if (varno == OUTER_VAR && dpns->outer_tlist)
     	{
    @@ -7628,7 +7628,7 @@ get_name_for_var_field(Var *var, int fieldno,
     		return NULL;			/* keep compiler quiet */
     	}
     
    -	if (attnum == InvalidAttrNumber)
    +	if (attphysnum == InvalidAttrNumber)
     	{
     		/* Var is whole-row reference to RTE, so select the right field */
     		return get_rte_attribute_name(rte, fieldno);
    @@ -7662,11 +7662,11 @@ get_name_for_var_field(Var *var, int fieldno,
     				if (rte->subquery)
     				{
     					TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
    -														attnum);
    +														attphysnum);
     
     					if (ste == NULL || ste->resjunk)
     						elog(ERROR, "subquery %s does not have attribute %d",
    -							 rte->eref->aliasname, attnum);
    +							 rte->eref->aliasname, attphysnum);
     					expr = (Node *) ste->expr;
     					if (IsA(expr, Var))
     					{
    @@ -7711,10 +7711,10 @@ get_name_for_var_field(Var *var, int fieldno,
     					if (!dpns->inner_plan)
     						elog(ERROR, "failed to find plan for subquery %s",
     							 rte->eref->aliasname);
    -					tle = get_tle_by_resno(dpns->inner_tlist, attnum);
    +					tle = get_tle_by_resno(dpns->inner_tlist, attphysnum);
     					if (!tle)
     						elog(ERROR, "bogus varattno for subquery var: %d",
    -							 attnum);
    +							 attphysnum);
     					Assert(netlevelsup == 0);
     					push_child_plan(dpns, dpns->inner_plan, &save_dpns);
     
    @@ -7730,8 +7730,8 @@ get_name_for_var_field(Var *var, int fieldno,
     			/* Join RTE --- recursively inspect the alias variable */
     			if (rte->joinaliasvars == NIL)
     				elog(ERROR, "cannot decompile join alias var in plan tree");
    -			Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
    -			expr = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
    +			Assert(attphysnum > 0 && attphysnum <= list_length(rte->joinaliasvars));
    +			expr = (Node *) list_nth(rte->joinaliasvars, attphysnum - 1);
     			Assert(expr != NULL);
     			/* we intentionally don't strip implicit coercions here */
     			if (IsA(expr, Var))
    @@ -7778,11 +7778,11 @@ get_name_for_var_field(Var *var, int fieldno,
     				{
     					Query	   *ctequery = (Query *) cte->ctequery;
     					TargetEntry *ste = get_tle_by_resno(GetCTETargetList(cte),
    -														attnum);
    +														attphysnum);
     
     					if (ste == NULL || ste->resjunk)
     						elog(ERROR, "subquery %s does not have attribute %d",
    -							 rte->eref->aliasname, attnum);
    +							 rte->eref->aliasname, attphysnum);
     					expr = (Node *) ste->expr;
     					if (IsA(expr, Var))
     					{
    @@ -7832,10 +7832,10 @@ get_name_for_var_field(Var *var, int fieldno,
     					if (!dpns->inner_plan)
     						elog(ERROR, "failed to find plan for CTE %s",
     							 rte->eref->aliasname);
    -					tle = get_tle_by_resno(dpns->inner_tlist, attnum);
    +					tle = get_tle_by_resno(dpns->inner_tlist, attphysnum);
     					if (!tle)
     						elog(ERROR, "bogus varattno for subquery var: %d",
    -							 attnum);
    +							 attphysnum);
     					Assert(netlevelsup == 0);
     					push_child_plan(dpns, dpns->inner_plan, &save_dpns);
     
    diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
    index fa1f589fad..04702b3ccc 100644
    --- a/src/backend/utils/adt/selfuncs.c
    +++ b/src/backend/utils/adt/selfuncs.c
    @@ -3973,24 +3973,24 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
     		{
     			ListCell   *lc3;
     			GroupVarInfo *varinfo = (GroupVarInfo *) lfirst(lc2);
    -			AttrNumber	attnum;
    +			AttrNumber	attphysnum;
     
     			Assert(varinfo->rel == rel);
     
     			/* simple Var, search in statistics keys directly */
     			if (IsA(varinfo->var, Var))
     			{
    -				attnum = ((Var *) varinfo->var)->varattno;
    +				attphysnum = ((Var *) varinfo->var)->varattno;
     
     				/*
     				 * Ignore system attributes - we don't support statistics on
     				 * them, so can't match them (and it'd fail as the values are
     				 * negative).
     				 */
    -				if (!AttrNumberIsForUserDefinedAttr(attnum))
    +				if (!AttrNumberIsForUserDefinedAttr(attphysnum))
     					continue;
     
    -				if (bms_is_member(attnum, info->keys))
    +				if (bms_is_member(attphysnum, info->keys))
     					nshared_vars++;
     
     				continue;
    @@ -4077,25 +4077,25 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
     			 */
     			if (IsA(varinfo->var, Var))
     			{
    -				AttrNumber	attnum = ((Var *) varinfo->var)->varattno;
    +				AttrNumber	attphysnum = ((Var *) varinfo->var)->varattno;
     
     				/*
     				 * Ignore expressions on system attributes. Can't rely on the
     				 * bms check for negative values.
     				 */
    -				if (!AttrNumberIsForUserDefinedAttr(attnum))
    +				if (!AttrNumberIsForUserDefinedAttr(attphysnum))
     					continue;
     
     				/* Is the variable covered by the statistics object? */
    -				if (!bms_is_member(attnum, matched_info->keys))
    +				if (!bms_is_member(attphysnum, matched_info->keys))
     					continue;
     
    -				attnum = attnum + attnum_offset;
    +				attphysnum = attphysnum + attnum_offset;
     
     				/* ensure sufficient offset */
    -				Assert(AttrNumberIsForUserDefinedAttr(attnum));
    +				Assert(AttrNumberIsForUserDefinedAttr(attphysnum));
     
    -				matched = bms_add_member(matched, attnum);
    +				matched = bms_add_member(matched, attphysnum);
     
     				found = true;
     			}
    @@ -4116,14 +4116,14 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
     
     				if (equal(varinfo->var, expr))
     				{
    -					AttrNumber	attnum = -(idx + 1);
    +					AttrNumber	attphysnum = -(idx + 1);
     
    -					attnum = attnum + attnum_offset;
    +					attphysnum = attphysnum + attnum_offset;
     
     					/* ensure sufficient offset */
    -					Assert(AttrNumberIsForUserDefinedAttr(attnum));
    +					Assert(AttrNumberIsForUserDefinedAttr(attphysnum));
     
    -					matched = bms_add_member(matched, attnum);
    +					matched = bms_add_member(matched, attphysnum);
     
     					/* there should be just one matching expression */
     					break;
    @@ -4148,15 +4148,15 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
     			/* check that all item attributes/expressions fit the match */
     			for (j = 0; j < tmpitem->nattributes; j++)
     			{
    -				AttrNumber	attnum = tmpitem->attributes[j];
    +				AttrNumber	attphysnum = tmpitem->attributes[j];
     
     				/*
     				 * Thanks to how we constructed the matched bitmap above, we
     				 * can just offset all attnums the same way.
     				 */
    -				attnum = attnum + attnum_offset;
    +				attphysnum = attphysnum + attnum_offset;
     
    -				if (!bms_is_member(attnum, matched))
    +				if (!bms_is_member(attphysnum, matched))
     				{
     					/* nah, it's not this item */
     					item = NULL;
    @@ -4189,28 +4189,28 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
     			/*
     			 * Let's look at plain variables first, because it's the most
     			 * common case and the check is quite cheap. We can simply get the
    -			 * attnum and check (with an offset) matched bitmap.
    +			 * attphysnum and check (with an offset) matched bitmap.
     			 */
     			if (IsA(varinfo->var, Var))
     			{
    -				AttrNumber	attnum = ((Var *) varinfo->var)->varattno;
    +				AttrNumber	attphysnum = ((Var *) varinfo->var)->varattno;
     
     				/*
     				 * If it's a system attribute, we're done. We don't support
     				 * extended statistics on system attributes, so it's clearly
     				 * not matched. Just keep the expression and continue.
     				 */
    -				if (!AttrNumberIsForUserDefinedAttr(attnum))
    +				if (!AttrNumberIsForUserDefinedAttr(attphysnum))
     				{
     					newlist = lappend(newlist, varinfo);
     					continue;
     				}
     
     				/* apply the same offset as above */
    -				attnum += attnum_offset;
    +				attphysnum += attnum_offset;
     
     				/* if it's not matched, keep the varinfo */
    -				if (!bms_is_member(attnum, matched))
    +				if (!bms_is_member(attphysnum, matched))
     					newlist = lappend(newlist, varinfo);
     
     				/* The rest of the loop deals with complex expressions. */
    @@ -7804,14 +7804,14 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
     	foreach(l, path->indexclauses)
     	{
     		IndexClause *iclause = lfirst_node(IndexClause, l);
    -		AttrNumber	attnum = index->indexkeys[iclause->indexcol];
    +		AttrNumber	attphysnum = index->indexkeys[iclause->indexcol];
     
     		/* attempt to lookup stats in relation for this index column */
    -		if (attnum != 0)
    +		if (attphysnum != 0)
     		{
     			/* Simple variable -- look to stats for the underlying table */
     			if (get_relation_stats_hook &&
    -				(*get_relation_stats_hook) (root, rte, attnum, &vardata))
    +				(*get_relation_stats_hook) (root, rte, attphysnum, &vardata))
     			{
     				/*
     				 * The hook took control of acquiring a stats tuple.  If it
    @@ -7826,7 +7826,7 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
     				vardata.statsTuple =
     					SearchSysCache3(STATRELATTINH,
     									ObjectIdGetDatum(rte->relid),
    -									Int16GetDatum(attnum),
    +									Int16GetDatum(attphysnum),
     									BoolGetDatum(false));
     				vardata.freefunc = ReleaseSysCache;
     			}
    @@ -7838,11 +7838,11 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
     			 * see if there's any stats for it.
     			 */
     
    -			/* get the attnum from the 0-based index. */
    -			attnum = iclause->indexcol + 1;
    +			/* get the attphysnum from the 0-based index. */
    +			attphysnum = iclause->indexcol + 1;
     
     			if (get_index_stats_hook &&
    -				(*get_index_stats_hook) (root, index->indexoid, attnum, &vardata))
    +				(*get_index_stats_hook) (root, index->indexoid, attphysnum, &vardata))
     			{
     				/*
     				 * The hook took control of acquiring a stats tuple.  If it
    @@ -7856,7 +7856,7 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
     			{
     				vardata.statsTuple = SearchSysCache3(STATRELATTINH,
     													 ObjectIdGetDatum(index->indexoid),
    -													 Int16GetDatum(attnum),
    +													 Int16GetDatum(attphysnum),
     													 BoolGetDatum(false));
     				vardata.freefunc = ReleaseSysCache;
     			}
    diff --git a/src/backend/utils/cache/attoptcache.c b/src/backend/utils/cache/attoptcache.c
    index 9e252a0891..0c9893ca95 100644
    --- a/src/backend/utils/cache/attoptcache.c
    +++ b/src/backend/utils/cache/attoptcache.c
    @@ -27,11 +27,11 @@
     /* Hash table for information about each attribute's options */
     static HTAB *AttoptCacheHash = NULL;
     
    -/* attrelid and attnum form the lookup key, and must appear first */
    +/* attrelid and attphysnum form the lookup key, and must appear first */
     typedef struct
     {
     	Oid			attrelid;
    -	int			attnum;
    +	int			attphysnum;
     } AttoptCacheKey;
     
     typedef struct
    @@ -90,7 +90,7 @@ InitializeAttoptCache(void)
     		CreateCacheMemoryContext();
     
     	/* Watch for invalidation events. */
    -	CacheRegisterSyscacheCallback(ATTNUM,
    +	CacheRegisterSyscacheCallback(ATTPHYSNUM,
     								  InvalidateAttoptCacheCallback,
     								  (Datum) 0);
     }
    @@ -100,7 +100,7 @@ InitializeAttoptCache(void)
      *		Fetch attribute options for a specified table OID.
      */
     AttributeOpts *
    -get_attribute_options(Oid attrelid, int attnum)
    +get_attribute_options(Oid attrelid, int attphysnum)
     {
     	AttoptCacheKey key;
     	AttoptCacheEntry *attopt;
    @@ -112,7 +112,7 @@ get_attribute_options(Oid attrelid, int attnum)
     		InitializeAttoptCache();
     	memset(&key, 0, sizeof(key));	/* make sure any padding bits are unset */
     	key.attrelid = attrelid;
    -	key.attnum = attnum;
    +	key.attphysnum = attphysnum;
     	attopt =
     		(AttoptCacheEntry *) hash_search(AttoptCacheHash,
     										 (void *) &key,
    @@ -124,9 +124,9 @@ get_attribute_options(Oid attrelid, int attnum)
     	{
     		AttributeOpts *opts;
     
    -		tp = SearchSysCache2(ATTNUM,
    +		tp = SearchSysCache2(ATTPHYSNUM,
     							 ObjectIdGetDatum(attrelid),
    -							 Int16GetDatum(attnum));
    +							 Int16GetDatum(attphysnum));
     
     		/*
     		 * If we don't find a valid HeapTuple, it must mean someone has
    @@ -140,7 +140,7 @@ get_attribute_options(Oid attrelid, int attnum)
     			Datum		datum;
     			bool		isNull;
     
    -			datum = SysCacheGetAttr(ATTNUM,
    +			datum = SysCacheGetAttr(ATTPHYSNUM,
     									tp,
     									Anum_pg_attribute_attoptions,
     									&isNull);
    diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
    index 6ae7c1f50b..9bf99c113b 100644
    --- a/src/backend/utils/cache/catcache.c
    +++ b/src/backend/utils/cache/catcache.c
    @@ -1909,13 +1909,13 @@ CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys)
     
     	for (i = 0; i < nkeys; i++)
     	{
    -		int			attnum = attnos[i];
    +		int			attphysnum = attnos[i];
     		Form_pg_attribute att;
     
     		/* system attribute are not supported in caches */
    -		Assert(attnum > 0);
    +		Assert(attphysnum > 0);
     
    -		att = TupleDescAttr(tupdesc, attnum - 1);
    +		att = TupleDescAttr(tupdesc, attphysnum - 1);
     
     		if (!att->attbyval)
     			pfree(DatumGetPointer(keys[i]));
    @@ -1940,8 +1940,8 @@ 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);
    +		int			attphysnum = attnos[i];
    +		Form_pg_attribute att = TupleDescAttr(tupdesc, attphysnum - 1);
     		Datum		src = srckeys[i];
     		NameData	srcname;
     
    diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
    index 1b7e11b93e..721fb194e7 100644
    --- a/src/backend/utils/cache/lsyscache.c
    +++ b/src/backend/utils/cache/lsyscache.c
    @@ -822,12 +822,12 @@ get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
      * otherwise a not-intended-for-user-consumption error is thrown.
      */
     char *
    -get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
    +get_attname(Oid relid, AttrNumber attphysnum, bool missing_ok)
     {
     	HeapTuple	tp;
     
    -	tp = SearchSysCache2(ATTNUM,
    -						 ObjectIdGetDatum(relid), Int16GetDatum(attnum));
    +	tp = SearchSysCache2(ATTPHYSNUM,
    +						 ObjectIdGetDatum(relid), Int16GetDatum(attphysnum));
     	if (HeapTupleIsValid(tp))
     	{
     		Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
    @@ -840,7 +840,7 @@ get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
     
     	if (!missing_ok)
     		elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -			 attnum, relid);
    +			 attphysnum, relid);
     	return NULL;
     }
     
    @@ -848,12 +848,12 @@ get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
      * get_attnum
      *
      *		Given the relation id and the attribute name,
    - *		return the "attnum" field from the attribute relation.
    + *		return the "attphysnum" field from the attribute relation.
      *
      *		Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
      */
     AttrNumber
    -get_attnum(Oid relid, const char *attname)
    +get_attphysnum(Oid relid, const char *attname)
     {
     	HeapTuple	tp;
     
    @@ -863,7 +863,7 @@ get_attnum(Oid relid, const char *attname)
     		Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
     		AttrNumber	result;
     
    -		result = att_tup->attnum;
    +		result = att_tup->attphysnum;
     		ReleaseSysCache(tp);
     		return result;
     	}
    @@ -880,18 +880,18 @@ get_attnum(Oid relid, const char *attname)
      *		Errors if not found.
      */
     int
    -get_attstattarget(Oid relid, AttrNumber attnum)
    +get_attstattarget(Oid relid, AttrNumber attphysnum)
     {
     	HeapTuple	tp;
     	Form_pg_attribute att_tup;
     	int			result;
     
    -	tp = SearchSysCache2(ATTNUM,
    +	tp = SearchSysCache2(ATTPHYSNUM,
     						 ObjectIdGetDatum(relid),
    -						 Int16GetDatum(attnum));
    +						 Int16GetDatum(attphysnum));
     	if (!HeapTupleIsValid(tp))
     		elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -			 attnum, relid);
    +			 attphysnum, relid);
     	att_tup = (Form_pg_attribute) GETSTRUCT(tp);
     	result = att_tup->attstattarget;
     	ReleaseSysCache(tp);
    @@ -910,18 +910,18 @@ get_attstattarget(Oid relid, AttrNumber attnum)
      *		Boolean test.
      */
     char
    -get_attgenerated(Oid relid, AttrNumber attnum)
    +get_attgenerated(Oid relid, AttrNumber attphysnum)
     {
     	HeapTuple	tp;
     	Form_pg_attribute att_tup;
     	char		result;
     
    -	tp = SearchSysCache2(ATTNUM,
    +	tp = SearchSysCache2(ATTPHYSNUM,
     						 ObjectIdGetDatum(relid),
    -						 Int16GetDatum(attnum));
    +						 Int16GetDatum(attphysnum));
     	if (!HeapTupleIsValid(tp))
     		elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -			 attnum, relid);
    +			 attphysnum, relid);
     	att_tup = (Form_pg_attribute) GETSTRUCT(tp);
     	result = att_tup->attgenerated;
     	ReleaseSysCache(tp);
    @@ -935,13 +935,13 @@ get_attgenerated(Oid relid, AttrNumber attnum)
      *		return the attribute type OID.
      */
     Oid
    -get_atttype(Oid relid, AttrNumber attnum)
    +get_atttype(Oid relid, AttrNumber attphysnum)
     {
     	HeapTuple	tp;
     
    -	tp = SearchSysCache2(ATTNUM,
    +	tp = SearchSysCache2(ATTPHYSNUM,
     						 ObjectIdGetDatum(relid),
    -						 Int16GetDatum(attnum));
    +						 Int16GetDatum(attphysnum));
     	if (HeapTupleIsValid(tp))
     	{
     		Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
    @@ -965,18 +965,18 @@ get_atttype(Oid relid, AttrNumber attnum)
      * raises an error if it can't obtain the information.
      */
     void
    -get_atttypetypmodcoll(Oid relid, AttrNumber attnum,
    +get_atttypetypmodcoll(Oid relid, AttrNumber attphysnum,
     					  Oid *typid, int32 *typmod, Oid *collid)
     {
     	HeapTuple	tp;
     	Form_pg_attribute att_tup;
     
    -	tp = SearchSysCache2(ATTNUM,
    +	tp = SearchSysCache2(ATTPHYSNUM,
     						 ObjectIdGetDatum(relid),
    -						 Int16GetDatum(attnum));
    +						 Int16GetDatum(attphysnum));
     	if (!HeapTupleIsValid(tp))
     		elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -			 attnum, relid);
    +			 attphysnum, relid);
     	att_tup = (Form_pg_attribute) GETSTRUCT(tp);
     
     	*typid = att_tup->atttypid;
    @@ -992,20 +992,20 @@ get_atttypetypmodcoll(Oid relid, AttrNumber attnum,
      *		return the attribute options text[] datum, if any.
      */
     Datum
    -get_attoptions(Oid relid, int16 attnum)
    +get_attoptions(Oid relid, int16 attphysnum)
     {
     	HeapTuple	tuple;
     	Datum		attopts;
     	Datum		result;
     	bool		isnull;
     
    -	tuple = SearchSysCache2(ATTNUM,
    +	tuple = SearchSysCache2(ATTPHYSNUM,
     							ObjectIdGetDatum(relid),
    -							Int16GetDatum(attnum));
    +							Int16GetDatum(attphysnum));
     
     	if (!HeapTupleIsValid(tuple))
     		elog(ERROR, "cache lookup failed for attribute %d of relation %u",
    -			 attnum, relid);
    +			 attphysnum, relid);
     
     	attopts = SysCacheGetAttr(ATTNAME, tuple, Anum_pg_attribute_attoptions,
     							  &isnull);
    @@ -3112,20 +3112,20 @@ getSubscriptingRoutines(Oid typid, Oid *typelemp)
      * plug-ins to control the result.
      */
     int32
    -get_attavgwidth(Oid relid, AttrNumber attnum)
    +get_attavgwidth(Oid relid, AttrNumber attphysnum)
     {
     	HeapTuple	tp;
     	int32		stawidth;
     
     	if (get_attavgwidth_hook)
     	{
    -		stawidth = (*get_attavgwidth_hook) (relid, attnum);
    +		stawidth = (*get_attavgwidth_hook) (relid, attphysnum);
     		if (stawidth > 0)
     			return stawidth;
     	}
     	tp = SearchSysCache3(STATRELATTINH,
     						 ObjectIdGetDatum(relid),
    -						 Int16GetDatum(attnum),
    +						 Int16GetDatum(attphysnum),
     						 BoolGetDatum(false));
     	if (HeapTupleIsValid(tp))
     	{
    diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
    index 0e8fda97f8..8a98060956 100644
    --- a/src/backend/utils/cache/relcache.c
    +++ b/src/backend/utils/cache/relcache.c
    @@ -537,7 +537,7 @@ RelationBuildTupleDesc(Relation relation)
     	constr->has_generated_stored = false;
     
     	/*
    -	 * Form a scan key that selects only user attributes (attnum > 0).
    +	 * Form a scan key that selects only user attributes (attphysnum > 0).
     	 * (Eliminating system attribute rows at the index level is lots faster
     	 * than fetching them.)
     	 */
    @@ -546,7 +546,7 @@ RelationBuildTupleDesc(Relation relation)
     				BTEqualStrategyNumber, F_OIDEQ,
     				ObjectIdGetDatum(RelationGetRelid(relation)));
     	ScanKeyInit(&skey[1],
    -				Anum_pg_attribute_attnum,
    +				Anum_pg_attribute_attphysnum,
     				BTGreaterStrategyNumber, F_INT2GT,
     				Int16GetDatum(0));
     
    @@ -557,7 +557,7 @@ RelationBuildTupleDesc(Relation relation)
     	 */
     	pg_attribute_desc = table_open(AttributeRelationId, AccessShareLock);
     	pg_attribute_scan = systable_beginscan(pg_attribute_desc,
    -										   AttributeRelidNumIndexId,
    +										   AttributeRelidPhysNumIndexId,
     										   criticalRelcachesBuilt,
     										   NULL,
     										   2, skey);
    @@ -570,16 +570,16 @@ RelationBuildTupleDesc(Relation relation)
     	while (HeapTupleIsValid(pg_attribute_tuple = systable_getnext(pg_attribute_scan)))
     	{
     		Form_pg_attribute attp;
    -		int			attnum;
    +		int			attphysnum;
     
     		attp = (Form_pg_attribute) GETSTRUCT(pg_attribute_tuple);
     
    -		attnum = attp->attnum;
    -		if (attnum <= 0 || attnum > RelationGetNumberOfAttributes(relation))
    +		attphysnum = attp->attphysnum;
    +		if (attphysnum <= 0 || attphysnum > RelationGetNumberOfAttributes(relation))
     			elog(ERROR, "invalid attribute number %d for relation \"%s\"",
    -				 attp->attnum, RelationGetRelationName(relation));
    +				 attp->attphysnum, RelationGetRelationName(relation));
     
    -		memcpy(TupleDescAttr(relation->rd_att, attnum - 1),
    +		memcpy(TupleDescAttr(relation->rd_att, attphysnum - 1),
     			   attp,
     			   ATTRIBUTE_FIXED_PART_SIZE);
     
    @@ -628,18 +628,18 @@ RelationBuildTupleDesc(Relation relation)
     				if (attp->attbyval)
     				{
     					/* for copy by val just copy the datum direct */
    -					attrmiss[attnum - 1].am_value = missval;
    +					attrmiss[attphysnum - 1].am_value = missval;
     				}
     				else
     				{
     					/* otherwise copy in the correct context */
     					oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
    -					attrmiss[attnum - 1].am_value = datumCopy(missval,
    +					attrmiss[attphysnum - 1].am_value = datumCopy(missval,
     															  attp->attbyval,
     															  attp->attlen);
     					MemoryContextSwitchTo(oldcxt);
     				}
    -				attrmiss[attnum - 1].am_present = true;
    +				attrmiss[attphysnum - 1].am_present = true;
     			}
     		}
     		need--;
    @@ -4046,7 +4046,7 @@ RelationCacheInitializePhase3(void)
     	{
     		load_critical_index(ClassOidIndexId,
     							RelationRelationId);
    -		load_critical_index(AttributeRelidNumIndexId,
    +		load_critical_index(AttributeRelidPhysNumIndexId,
     							AttributeRelationId);
     		load_critical_index(IndexRelidIndexId,
     							IndexRelationId);
    @@ -5708,21 +5708,21 @@ RelationGetIndexRawAttOptions(Relation indexrel)
     	Oid			indexrelid = RelationGetRelid(indexrel);
     	int16		natts = RelationGetNumberOfAttributes(indexrel);
     	Datum	   *options = NULL;
    -	int16		attnum;
    +	int16		attphysnum;
     
    -	for (attnum = 1; attnum <= natts; attnum++)
    +	for (attphysnum = 1; attphysnum <= natts; attphysnum++)
     	{
     		if (indexrel->rd_indam->amoptsprocnum == 0)
     			continue;
     
    -		if (!OidIsValid(index_getprocid(indexrel, attnum,
    +		if (!OidIsValid(index_getprocid(indexrel, attphysnum,
     										indexrel->rd_indam->amoptsprocnum)))
     			continue;
     
     		if (!options)
     			options = palloc0(sizeof(Datum) * natts);
     
    -		options[attnum - 1] = get_attoptions(indexrelid, attnum);
    +		options[attphysnum - 1] = get_attoptions(indexrelid, attphysnum);
     	}
     
     	return options;
    @@ -5767,7 +5767,7 @@ RelationGetIndexAttOptions(Relation relation, bool copy)
     
     	for (i = 0; i < natts; i++)
     	{
    -		if (criticalRelcachesBuilt && relid != AttributeRelidNumIndexId)
    +		if (criticalRelcachesBuilt && relid != AttributeRelidPhysNumIndexId)
     		{
     			Datum		attoptions = get_attoptions(relid, i + 1);
     
    @@ -5827,16 +5827,16 @@ errtable(Relation rel)
      * easier and less error-prone than getting the column name for themselves.
      */
     int
    -errtablecol(Relation rel, int attnum)
    +errtablecol(Relation rel, int attphysnum)
     {
     	TupleDesc	reldesc = RelationGetDescr(rel);
     	const char *colname;
     
     	/* Use reldesc if it's a user attribute, else consult the catalogs */
    -	if (attnum > 0 && attnum <= reldesc->natts)
    -		colname = NameStr(TupleDescAttr(reldesc, attnum - 1)->attname);
    +	if (attphysnum > 0 && attphysnum <= reldesc->natts)
    +		colname = NameStr(TupleDescAttr(reldesc, attphysnum - 1)->attname);
     	else
    -		colname = get_attname(RelationGetRelid(rel), attnum, false);
    +		colname = get_attname(RelationGetRelid(rel), attphysnum, false);
     
     	return errtablecolname(rel, colname);
     }
    diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
    index 1912b12146..9751ad6a22 100644
    --- a/src/backend/utils/cache/syscache.c
    +++ b/src/backend/utils/cache/syscache.c
    @@ -200,12 +200,12 @@ static const struct cachedesc cacheinfo[] = {
     		},
     		32
     	},
    -	{AttributeRelationId,		/* ATTNUM */
    -		AttributeRelidNumIndexId,
    +	{AttributeRelationId,		/* ATTPHYSNUM */
    +		AttributeRelidPhysNumIndexId,
     		2,
     		{
     			Anum_pg_attribute_attrelid,
    -			Anum_pg_attribute_attnum,
    +			Anum_pg_attribute_attphysnum,
     			0,
     			0
     		},
    @@ -1368,19 +1368,19 @@ SearchSysCacheExistsAttName(Oid relid, const char *attname)
     /*
      * SearchSysCacheAttNum
      *
    - * This routine is equivalent to SearchSysCache on the ATTNUM cache,
    + * This routine is equivalent to SearchSysCache on the ATTPHYSNUM cache,
      * except that it will return NULL if the found attribute is marked
      * attisdropped.  This is convenient for callers that want to act as
      * though dropped attributes don't exist.
      */
     HeapTuple
    -SearchSysCacheAttNum(Oid relid, int16 attnum)
    +SearchSysCacheAttNum(Oid relid, int16 attphysnum)
     {
     	HeapTuple	tuple;
     
    -	tuple = SearchSysCache2(ATTNUM,
    +	tuple = SearchSysCache2(ATTPHYSNUM,
     							ObjectIdGetDatum(relid),
    -							Int16GetDatum(attnum));
    +							Int16GetDatum(attphysnum));
     	if (!HeapTupleIsValid(tuple))
     		return NULL;
     	if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
    @@ -1397,12 +1397,12 @@ SearchSysCacheAttNum(Oid relid, int16 attnum)
      * As above, an attisdropped-aware version of SearchSysCacheCopy.
      */
     HeapTuple
    -SearchSysCacheCopyAttNum(Oid relid, int16 attnum)
    +SearchSysCacheCopyAttNum(Oid relid, int16 attphysnum)
     {
     	HeapTuple	tuple,
     				newtuple;
     
    -	tuple = SearchSysCacheAttNum(relid, attnum);
    +	tuple = SearchSysCacheAttNum(relid, attphysnum);
     	if (!HeapTupleIsValid(tuple))
     		return NULL;
     	newtuple = heap_copytuple(tuple);
    diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
    index ed6de7ca94..b6fb9391e7 100644
    --- a/src/bin/initdb/initdb.c
    +++ b/src/bin/initdb/initdb.c
    @@ -1612,7 +1612,7 @@ setup_privileges(FILE *cmdfd)
     		"    SELECT"
     		"        pg_class.oid,"
     		"        (SELECT oid FROM pg_class WHERE relname = 'pg_class'),"
    -		"        pg_attribute.attnum,"
    +		"        pg_attribute.attphysnum,"
     		"        pg_attribute.attacl,"
     		"        'i'"
     		"    FROM"
    diff --git a/src/bin/pg_amcheck/pg_amcheck.c b/src/bin/pg_amcheck/pg_amcheck.c
    index 3cff319f02..dc043f73ae 100644
    --- a/src/bin/pg_amcheck/pg_amcheck.c
    +++ b/src/bin/pg_amcheck/pg_amcheck.c
    @@ -802,7 +802,7 @@ prepare_heap_command(PQExpBuffer sql, RelationInfo *rel, PGconn *conn)
     {
     	resetPQExpBuffer(sql);
     	appendPQExpBuffer(sql,
    -					  "SELECT v.blkno, v.offnum, v.attnum, v.msg "
    +					  "SELECT v.blkno, v.offnum, v.attphysnum, v.msg "
     					  "FROM pg_catalog.pg_class c, %s.verify_heapam("
     					  "\nrelation := c.oid, on_error_stop := %s, check_toast := %s, skip := '%s'",
     					  rel->datinfo->amcheck_schema,
    @@ -1016,7 +1016,7 @@ verify_heap_slot_handler(PGresult *res, PGconn *conn, void *context)
     					   rel->datinfo->datname, rel->nspname, rel->relname,
     					   PQgetvalue(res, i, 0),	/* blkno */
     					   PQgetvalue(res, i, 1),	/* offnum */
    -					   PQgetvalue(res, i, 2));	/* attnum */
    +					   PQgetvalue(res, i, 2));	/* attphysnum */
     
     			else if (!PQgetisnull(res, i, 1))
     				printf(_("heap table \"%s.%s.%s\", block %s, offset %s:\n"),
    diff --git a/src/bin/pg_amcheck/t/003_check.pl b/src/bin/pg_amcheck/t/003_check.pl
    index 0cf67065d6..224287e6f5 100644
    --- a/src/bin/pg_amcheck/t/003_check.pl
    +++ b/src/bin/pg_amcheck/t/003_check.pl
    @@ -172,7 +172,7 @@ for my $dbname (qw(db1 db2 db3))
     											 endblock bigint default null,
     											 blkno OUT bigint,
     											 offnum OUT integer,
    -											 attnum OUT integer,
    +											 attphysnum OUT integer,
     											 msg OUT text)
     		RETURNS SETOF record AS $$
     		BEGIN
    diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
    index 7cc9c72e49..58e07f008c 100644
    --- a/src/bin/pg_dump/pg_dump.c
    +++ b/src/bin/pg_dump/pg_dump.c
    @@ -4171,7 +4171,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
     							 "       FROM\n"
     							 "         pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
     							 "         pg_catalog.pg_attribute\n"
    -							 "      WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n"
    +							 "      WHERE attrelid = pr.prrelid AND attphysnum = prattrs[s])\n"
     							 "  ELSE NULL END) prattrs "
     							 "FROM pg_catalog.pg_publication_rel pr");
     	else
    @@ -6719,11 +6719,11 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
     						  "inh.inhparent AS parentidx, "
     						  "i.indnkeyatts AS indnkeyatts, "
     						  "i.indnatts AS indnatts, "
    -						  "(SELECT pg_catalog.array_agg(attnum ORDER BY attnum) "
    +						  "(SELECT pg_catalog.array_agg(attphysnum ORDER BY attphysnum) "
     						  "  FROM pg_catalog.pg_attribute "
     						  "  WHERE attrelid = i.indexrelid AND "
     						  "    attstattarget >= 0) AS indstatcols, "
    -						  "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attnum) "
    +						  "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attphysnum) "
     						  "  FROM pg_catalog.pg_attribute "
     						  "  WHERE attrelid = i.indexrelid AND "
     						  "    attstattarget >= 0) AS indstatvals, ");
    @@ -8130,7 +8130,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
     	appendPQExpBufferStr(q,
     						 "SELECT\n"
     						 "a.attrelid,\n"
    -						 "a.attnum,\n"
    +						 "a.attphysnum,\n"
     						 "a.attname,\n"
     						 "a.atttypmod,\n"
     						 "a.attstattarget,\n"
    @@ -8188,8 +8188,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
     					  "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
     					  "LEFT JOIN pg_catalog.pg_type t "
     					  "ON (a.atttypid = t.oid)\n"
    -					  "WHERE a.attnum > 0::pg_catalog.int2\n"
    -					  "ORDER BY a.attrelid, a.attnum",
    +					  "WHERE a.attphysnum > 0::pg_catalog.int2\n"
    +					  "ORDER BY a.attrelid, a.attphysnum",
     					  tbloids->data);
     
     	res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
    @@ -8197,7 +8197,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
     	ntups = PQntuples(res);
     
     	i_attrelid = PQfnumber(res, "attrelid");
    -	i_attnum = PQfnumber(res, "attnum");
    +	i_attnum = PQfnumber(res, "attphysnum");
     	i_attname = PQfnumber(res, "attname");
     	i_atttypname = PQfnumber(res, "atttypname");
     	i_atttypmod = PQfnumber(res, "atttypmod");
    @@ -11010,7 +11010,7 @@ dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
     		 */
     		appendPQExpBufferStr(query,
     							 "PREPARE dumpCompositeType(pg_catalog.oid) AS\n"
    -							 "SELECT a.attname, a.attnum, "
    +							 "SELECT a.attname, a.attphysnum, "
     							 "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
     							 "a.attlen, a.attalign, a.attisdropped, "
     							 "CASE WHEN a.attcollation <> at.typcollation "
    @@ -11019,7 +11019,7 @@ dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
     							 "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
     							 "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
     							 "WHERE ct.oid = $1 "
    -							 "ORDER BY a.attnum");
    +							 "ORDER BY a.attphysnum");
     
     		ExecuteSqlStatement(fout, query->data);
     
    @@ -11214,7 +11214,7 @@ dumpCompositeTypeColComments(Archive *fout, const TypeInfo *tyinfo,
     	target = createPQExpBuffer();
     
     	ntups = PQntuples(res);
    -	i_attnum = PQfnumber(res, "attnum");
    +	i_attnum = PQfnumber(res, "attphysnum");
     	i_attname = PQfnumber(res, "attname");
     	i_attisdropped = PQfnumber(res, "attisdropped");
     	while (ncomments > 0)
    @@ -14869,11 +14869,11 @@ dumpTable(Archive *fout, const TableInfo *tbinfo)
     									 "LEFT JOIN pg_catalog.pg_init_privs pip ON "
     									 "(at.attrelid = pip.objoid "
     									 "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass "
    -									 "AND at.attnum = pip.objsubid) "
    +									 "AND at.attphysnum = pip.objsubid) "
     									 "WHERE at.attrelid = $1 AND "
     									 "NOT at.attisdropped "
     									 "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) "
    -									 "ORDER BY at.attnum");
    +									 "ORDER BY at.attphysnum");
     			}
     			else
     			{
    @@ -14883,7 +14883,7 @@ dumpTable(Archive *fout, const TableInfo *tbinfo)
     									 "FROM pg_catalog.pg_attribute "
     									 "WHERE attrelid = $1 AND NOT attisdropped "
     									 "AND attacl IS NOT NULL "
    -									 "ORDER BY attnum");
    +									 "ORDER BY attphysnum");
     			}
     
     			ExecuteSqlStatement(fout, query->data);
    diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
    index d1ae699171..a25ec298fd 100644
    --- a/src/bin/psql/describe.c
    +++ b/src/bin/psql/describe.c
    @@ -1731,21 +1731,42 @@ describeOneTableDetails(const char *schemaname,
     			goto error_return;
     
     		/* Get the column that owns this sequence */
    -		printfPQExpBuffer(&buf, "SELECT pg_catalog.quote_ident(nspname) || '.' ||"
    -						  "\n   pg_catalog.quote_ident(relname) || '.' ||"
    -						  "\n   pg_catalog.quote_ident(attname),"
    -						  "\n   d.deptype"
    -						  "\nFROM pg_catalog.pg_class c"
    -						  "\nINNER JOIN pg_catalog.pg_depend d ON c.oid=d.refobjid"
    -						  "\nINNER JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace"
    -						  "\nINNER JOIN pg_catalog.pg_attribute a ON ("
    -						  "\n a.attrelid=c.oid AND"
    -						  "\n a.attnum=d.refobjsubid)"
    -						  "\nWHERE d.classid='pg_catalog.pg_class'::pg_catalog.regclass"
    -						  "\n AND d.refclassid='pg_catalog.pg_class'::pg_catalog.regclass"
    -						  "\n AND d.objid='%s'"
    -						  "\n AND d.deptype IN ('a', 'i')",
    -						  oid);
    +		if (pset.sversion >= 150000) /* FIXME - bump me when pg15 branched */
    +		{
    +			printfPQExpBuffer(&buf, "SELECT pg_catalog.quote_ident(nspname) || '.' ||"
    +							  "\n   pg_catalog.quote_ident(relname) || '.' ||"
    +							  "\n   pg_catalog.quote_ident(attname),"
    +							  "\n   d.deptype"
    +							  "\nFROM pg_catalog.pg_class c"
    +							  "\nINNER JOIN pg_catalog.pg_depend d ON c.oid=d.refobjid"
    +							  "\nINNER JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace"
    +							  "\nINNER JOIN pg_catalog.pg_attribute a ON ("
    +							  "\n a.attrelid=c.oid AND"
    +							  "\n a.attphysnum=d.refobjsubid)"
    +							  "\nWHERE d.classid='pg_catalog.pg_class'::pg_catalog.regclass"
    +							  "\n AND d.refclassid='pg_catalog.pg_class'::pg_catalog.regclass"
    +							  "\n AND d.objid='%s'"
    +							  "\n AND d.deptype IN ('a', 'i')",
    +							  oid);
    +		}
    +		else
    +		{
    +			printfPQExpBuffer(&buf, "SELECT pg_catalog.quote_ident(nspname) || '.' ||"
    +							  "\n   pg_catalog.quote_ident(relname) || '.' ||"
    +							  "\n   pg_catalog.quote_ident(attname),"
    +							  "\n   d.deptype"
    +							  "\nFROM pg_catalog.pg_class c"
    +							  "\nINNER JOIN pg_catalog.pg_depend d ON c.oid=d.refobjid"
    +							  "\nINNER JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace"
    +							  "\nINNER JOIN pg_catalog.pg_attribute a ON ("
    +							  "\n a.attrelid=c.oid AND"
    +							  "\n a.attnum=d.refobjsubid)"
    +							  "\nWHERE d.classid='pg_catalog.pg_class'::pg_catalog.regclass"
    +							  "\n AND d.refclassid='pg_catalog.pg_class'::pg_catalog.regclass"
    +							  "\n AND d.objid='%s'"
    +							  "\n AND d.deptype IN ('a', 'i')",
    +							  oid);
    +		}
     
     		result = PSQLexec(buf.data);
     
    @@ -1819,11 +1840,23 @@ describeOneTableDetails(const char *schemaname,
     	if (show_column_details)
     	{
     		/* use "pretty" mode for expression to avoid excessive parentheses */
    -		appendPQExpBufferStr(&buf,
    -							 ",\n  (SELECT pg_catalog.pg_get_expr(d.adbin, d.adrelid, true)"
    -							 "\n   FROM pg_catalog.pg_attrdef d"
    -							 "\n   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef)"
    -							 ",\n  a.attnotnull");
    +		if (pset.sversion >= 150000) /* FIXME - bump me when pg15 branched */
    +		{
    +			appendPQExpBufferStr(&buf,
    +								 ",\n  (SELECT pg_catalog.pg_get_expr(d.adbin, d.adrelid, true)"
    +								 "\n   FROM pg_catalog.pg_attrdef d"
    +								 "\n   WHERE d.adrelid = a.attrelid AND d.adnum = a.attphysnum AND a.atthasdef)"
    +								 ",\n  a.attnotnull");
    +		}
    +		else
    +		{
    +			appendPQExpBufferStr(&buf,
    +								 ",\n  (SELECT pg_catalog.pg_get_expr(d.adbin, d.adrelid, true)"
    +								 "\n   FROM pg_catalog.pg_attrdef d"
    +								 "\n   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef)"
    +								 ",\n  a.attnotnull");
    +		}
    +
     		attrdef_col = cols++;
     		attnotnull_col = cols++;
     		appendPQExpBufferStr(&buf, ",\n  (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t\n"
    @@ -1843,7 +1876,15 @@ describeOneTableDetails(const char *schemaname,
     	if (tableinfo.relkind == RELKIND_INDEX ||
     		tableinfo.relkind == RELKIND_PARTITIONED_INDEX)
     	{
    -		if (pset.sversion >= 110000)
    +		if (pset.sversion >= 150000) /* FIXME - bump me when pg15 branched */
    +		{
    +			appendPQExpBuffer(&buf, ",\n  CASE WHEN a.attphysnum <= (SELECT i.indnkeyatts FROM pg_catalog.pg_index i WHERE i.indexrelid = '%s') THEN '%s' ELSE '%s' END AS is_key",
    +							  oid,
    +							  gettext_noop("yes"),
    +							  gettext_noop("no"));
    +			isindexkey_col = cols++;
    +		}
    +		else if (pset.sversion >= 110000)
     		{
     			appendPQExpBuffer(&buf, ",\n  CASE WHEN a.attnum <= (SELECT i.indnkeyatts FROM pg_catalog.pg_index i WHERE i.indexrelid = '%s') THEN '%s' ELSE '%s' END AS is_key",
     							  oid,
    @@ -1851,7 +1892,11 @@ describeOneTableDetails(const char *schemaname,
     							  gettext_noop("no"));
     			isindexkey_col = cols++;
     		}
    -		appendPQExpBufferStr(&buf, ",\n  pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE) AS indexdef");
    +
    +		if (pset.sversion >= 150000) /* FIXME - bump me when pg15 branched */
    +			appendPQExpBufferStr(&buf, ",\n  pg_catalog.pg_get_indexdef(a.attrelid, a.attphysnum, TRUE) AS indexdef");
    +		else
    +			appendPQExpBufferStr(&buf, ",\n  pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE) AS indexdef");
     		indexdef_col = cols++;
     	}
     	/* FDW options for foreign table column */
    @@ -1901,14 +1946,25 @@ describeOneTableDetails(const char *schemaname,
     			tableinfo.relkind == RELKIND_COMPOSITE_TYPE ||
     			tableinfo.relkind == RELKIND_PARTITIONED_TABLE)
     		{
    -			appendPQExpBufferStr(&buf, ",\n  pg_catalog.col_description(a.attrelid, a.attnum)");
    +			if (pset.sversion >= 150000) /* FIXME - bump me when pg15 branched */
    +				appendPQExpBufferStr(&buf, ",\n  pg_catalog.col_description(a.attrelid, a.attphysnum)");
    +			else
    +				appendPQExpBufferStr(&buf, ",\n  pg_catalog.col_description(a.attrelid, a.attnum)");
     			attdescr_col = cols++;
     		}
     	}
     
     	appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_attribute a");
    -	appendPQExpBuffer(&buf, "\nWHERE a.attrelid = '%s' AND a.attnum > 0 AND NOT a.attisdropped", oid);
    -	appendPQExpBufferStr(&buf, "\nORDER BY a.attnum;");
    +	if (pset.sversion >= 150000) /* FIXME - bump me when pg15 branched */
    +	{
    +		appendPQExpBuffer(&buf, "\nWHERE a.attrelid = '%s' AND a.attphysnum > 0 AND NOT a.attisdropped", oid);
    +		appendPQExpBufferStr(&buf, "\nORDER BY a.attphysnum;");
    +	}
    +	else
    +	{
    +		appendPQExpBuffer(&buf, "\nWHERE a.attrelid = '%s' AND a.attnum > 0 AND NOT a.attisdropped", oid);
    +		appendPQExpBufferStr(&buf, "\nORDER BY a.attnum;");
    +	}
     
     	res = PSQLexec(buf.data);
     	if (!res)
    @@ -2930,7 +2986,39 @@ describeOneTableDetails(const char *schemaname,
     		/* print any publications */
     		if (pset.sversion >= 100000)
     		{
    -			if (pset.sversion >= 150000)
    +			if (pset.sversion >= 150000) /* FIXME - bump me when pg15 branched */
    +			{
    +				printfPQExpBuffer(&buf,
    +								  "SELECT pubname\n"
    +								  "     , NULL\n"
    +								  "     , NULL\n"
    +								  "FROM pg_catalog.pg_publication p\n"
    +								  "     JOIN pg_catalog.pg_publication_namespace pn ON p.oid = pn.pnpubid\n"
    +								  "     JOIN pg_catalog.pg_class pc ON pc.relnamespace = pn.pnnspid\n"
    +								  "WHERE pc.oid ='%s' and pg_catalog.pg_relation_is_publishable('%s')\n"
    +								  "UNION\n"
    +								  "SELECT pubname\n"
    +								  "     , pg_get_expr(pr.prqual, c.oid)\n"
    +								  "     , (CASE WHEN pr.prattrs IS NOT NULL THEN\n"
    +								  "         (SELECT string_agg(attname, ', ')\n"
    +								  "           FROM pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
    +								  "                pg_catalog.pg_attribute\n"
    +								  "          WHERE attrelid = pr.prrelid AND attphysnum = prattrs[s])\n"
    +								  "        ELSE NULL END) "
    +								  "FROM pg_catalog.pg_publication p\n"
    +								  "     JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid\n"
    +								  "     JOIN pg_catalog.pg_class c ON c.oid = pr.prrelid\n"
    +								  "WHERE pr.prrelid = '%s'\n"
    +								  "UNION\n"
    +								  "SELECT pubname\n"
    +								  "     , NULL\n"
    +								  "     , NULL\n"
    +								  "FROM pg_catalog.pg_publication p\n"
    +								  "WHERE p.puballtables AND pg_catalog.pg_relation_is_publishable('%s')\n"
    +								  "ORDER BY 1;",
    +								  oid, oid, oid, oid);
    +			}
    +			else if (pset.sversion >= 150000)
     			{
     				printfPQExpBuffer(&buf,
     								  "SELECT pubname\n"
    @@ -4609,7 +4697,7 @@ listExtendedStats(const char *pattern)
     						  "   FROM pg_catalog.unnest(es.stxkeys) s(attnum) \n"
     						  "   JOIN pg_catalog.pg_attribute a \n"
     						  "   ON (es.stxrelid = a.attrelid \n"
    -						  "   AND a.attnum = s.attnum \n"
    +						  "   AND a.attnum = s.attsnum \n"
     						  "   AND NOT a.attisdropped)), \n"
     						  "es.stxrelid::pg_catalog.regclass) AS \"%s\"",
     						  gettext_noop("Definition"));
    @@ -6279,7 +6367,21 @@ describePublications(const char *pattern)
     			/* Get the tables for the specified publication */
     			printfPQExpBuffer(&buf,
     							  "SELECT n.nspname, c.relname");
    -			if (pset.sversion >= 150000)
    +			if (pset.sversion >= 150000) /* FIXME - bump me when pg15 branched */
    +			{
    +				appendPQExpBufferStr(&buf,
    +									 ", pg_get_expr(pr.prqual, c.oid)");
    +				appendPQExpBufferStr(&buf,
    +									 ", (CASE WHEN pr.prattrs IS NOT NULL THEN\n"
    +									 "     pg_catalog.array_to_string("
    +									 "      ARRAY(SELECT attname\n"
    +									 "              FROM\n"
    +									 "                pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
    +									 "                pg_catalog.pg_attribute\n"
    +									 "        WHERE attrelid = c.oid AND attphysnum = prattrs[s]), ', ')\n"
    +									 "       ELSE NULL END)");
    +			}
    +			else if (pset.sversion >= 150000)
     			{
     				appendPQExpBufferStr(&buf,
     									 ", pg_get_expr(pr.prqual, c.oid)");
    diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
    index bd44a1d55d..df5df475b8 100644
    --- a/src/bin/psql/tab-complete.c
    +++ b/src/bin/psql/tab-complete.c
    @@ -516,7 +516,7 @@ static const SchemaQuery Query_for_list_of_arguments = {
     
     static const SchemaQuery Query_for_list_of_attributes = {
     	.catname = "pg_catalog.pg_attribute a, pg_catalog.pg_class c",
    -	.selcondition = "c.oid = a.attrelid and a.attnum > 0 and not a.attisdropped",
    +	.selcondition = "c.oid = a.attrelid and a.attphysnum > 0 and not a.attisdropped",
     	.result = "a.attname",
     	.refname = "c.relname",
     	.refviscondition = "pg_catalog.pg_table_is_visible(c.oid)",
    @@ -525,7 +525,7 @@ static const SchemaQuery Query_for_list_of_attributes = {
     
     static const SchemaQuery Query_for_list_of_attribute_numbers = {
     	.catname = "pg_catalog.pg_attribute a, pg_catalog.pg_class c",
    -	.selcondition = "c.oid = a.attrelid and a.attnum > 0 and not a.attisdropped",
    +	.selcondition = "c.oid = a.attrelid and a.attphysnum > 0 and not a.attisdropped",
     	.result = "a.attnum::pg_catalog.text",
     	.refname = "c.relname",
     	.refviscondition = "pg_catalog.pg_table_is_visible(c.oid)",
    diff --git a/src/include/access/genam.h b/src/include/access/genam.h
    index 134b20f1e6..4d95e2801a 100644
    --- a/src/include/access/genam.h
    +++ b/src/include/access/genam.h
    @@ -183,15 +183,15 @@ extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info,
     extern IndexBulkDeleteResult *index_vacuum_cleanup(IndexVacuumInfo *info,
     												   IndexBulkDeleteResult *istat);
     extern bool index_can_return(Relation indexRelation, int attno);
    -extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum,
    +extern RegProcedure index_getprocid(Relation irel, AttrNumber attphysnum,
     									uint16 procnum);
    -extern FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum,
    +extern FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attphysnum,
     								   uint16 procnum);
     extern void index_store_float8_orderby_distances(IndexScanDesc scan,
     												 Oid *orderByTypes,
     												 IndexOrderByDistance *distances,
     												 bool recheckOrderBy);
    -extern bytea *index_opclass_options(Relation relation, AttrNumber attnum,
    +extern bytea *index_opclass_options(Relation relation, AttrNumber attphysnum,
     									Datum attoptions, bool validate);
     
     
    diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
    index 2935d2f353..733686d724 100644
    --- a/src/include/access/gin_private.h
    +++ b/src/include/access/gin_private.h
    @@ -95,13 +95,13 @@ extern Buffer GinNewBuffer(Relation index);
     extern void GinInitBuffer(Buffer b, uint32 f);
     extern void GinInitPage(Page page, uint32 f, Size pageSize);
     extern void GinInitMetabuffer(Buffer b);
    -extern int	ginCompareEntries(GinState *ginstate, OffsetNumber attnum,
    +extern int	ginCompareEntries(GinState *ginstate, OffsetNumber attphysnum,
     							  Datum a, GinNullCategory categorya,
     							  Datum b, GinNullCategory categoryb);
     extern int	ginCompareAttEntries(GinState *ginstate,
     								 OffsetNumber attnuma, Datum a, GinNullCategory categorya,
     								 OffsetNumber attnumb, Datum b, GinNullCategory categoryb);
    -extern Datum *ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
    +extern Datum *ginExtractEntries(GinState *ginstate, OffsetNumber attphysnum,
     								Datum value, bool isNull,
     								int32 *nentries, GinNullCategory **categories);
     
    @@ -119,7 +119,7 @@ extern bool gininsert(Relation index, Datum *values, bool *isnull,
     					  bool indexUnchanged,
     					  struct IndexInfo *indexInfo);
     extern void ginEntryInsert(GinState *ginstate,
    -						   OffsetNumber attnum, Datum key, GinNullCategory category,
    +						   OffsetNumber attphysnum, Datum key, GinNullCategory category,
     						   ItemPointerData *items, uint32 nitem,
     						   GinStatsData *buildStats);
     
    @@ -210,13 +210,13 @@ extern void ginInsertValue(GinBtree btree, GinBtreeStack *stack,
     
     /* ginentrypage.c */
     extern IndexTuple GinFormTuple(GinState *ginstate,
    -							   OffsetNumber attnum, Datum key, GinNullCategory category,
    +							   OffsetNumber attphysnum, Datum key, GinNullCategory category,
     							   Pointer data, Size dataSize, int nipd, bool errorTooBig);
    -extern void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
    +extern void ginPrepareEntryScan(GinBtree btree, OffsetNumber attphysnum,
     								Datum key, GinNullCategory category,
     								GinState *ginstate);
     extern void ginEntryFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage);
    -extern ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum,
    +extern ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attphysnum,
     								IndexTuple itup, int *nitems);
     
     /* gindatapage.c */
    @@ -302,7 +302,7 @@ typedef struct GinScanKeyData
     	Pointer    *extra_data;
     	StrategyNumber strategy;
     	int32		searchMode;
    -	OffsetNumber attnum;
    +	OffsetNumber attphysnum;
     
     	/*
     	 * An excludeOnly scan key is not able to enumerate all matching tuples.
    @@ -340,7 +340,7 @@ typedef struct GinScanEntryData
     	Pointer		extra_data;
     	StrategyNumber strategy;
     	int32		searchMode;
    -	OffsetNumber attnum;
    +	OffsetNumber attphysnum;
     
     	/* Current page in posting tree */
     	Buffer		buffer;
    @@ -419,7 +419,7 @@ typedef struct GinEntryAccumulator
     	RBTNode		rbtnode;
     	Datum		key;
     	GinNullCategory category;
    -	OffsetNumber attnum;
    +	OffsetNumber attphysnum;
     	bool		shouldSort;
     	ItemPointerData *list;
     	uint32		maxcount;		/* allocated size of list[] */
    @@ -438,12 +438,12 @@ typedef struct
     
     extern void ginInitBA(BuildAccumulator *accum);
     extern void ginInsertBAEntries(BuildAccumulator *accum,
    -							   ItemPointer heapptr, OffsetNumber attnum,
    +							   ItemPointer heapptr, OffsetNumber attphysnum,
     							   Datum *entries, GinNullCategory *categories,
     							   int32 nentries);
     extern void ginBeginBAScan(BuildAccumulator *accum);
     extern ItemPointerData *ginGetBAEntry(BuildAccumulator *accum,
    -									  OffsetNumber *attnum, Datum *key, GinNullCategory *category,
    +									  OffsetNumber *attphysnum, Datum *key, GinNullCategory *category,
     									  uint32 *n);
     
     /* ginfast.c */
    @@ -460,7 +460,7 @@ extern void ginHeapTupleFastInsert(GinState *ginstate,
     								   GinTupleCollector *collector);
     extern void ginHeapTupleFastCollect(GinState *ginstate,
     									GinTupleCollector *collector,
    -									OffsetNumber attnum, Datum value, bool isNull,
    +									OffsetNumber attphysnum, Datum value, bool isNull,
     									ItemPointer ht_ctid);
     extern void ginInsertCleanup(GinState *ginstate, bool full_clean,
     							 bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats);
    diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h
    index 51a60eda08..a04c5df02e 100644
    --- a/src/include/access/htup_details.h
    +++ b/src/include/access/htup_details.h
    @@ -697,13 +697,13 @@ extern void heap_fill_tuple(TupleDesc tupleDesc,
     							Datum *values, bool *isnull,
     							char *data, Size data_size,
     							uint16 *infomask, bits8 *bit);
    -extern bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc);
    -extern Datum nocachegetattr(HeapTuple tup, int attnum,
    +extern bool heap_attisnull(HeapTuple tup, int attphysnum, TupleDesc tupleDesc);
    +extern Datum nocachegetattr(HeapTuple tup, int attphysnum,
     							TupleDesc att);
    -extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
    +extern Datum heap_getsysattr(HeapTuple tup, int attphysnum, TupleDesc tupleDesc,
     							 bool *isnull);
     extern Datum getmissingattr(TupleDesc tupleDesc,
    -							int attnum, bool *isnull);
    +							int attphysnum, bool *isnull);
     extern HeapTuple heap_copytuple(HeapTuple tuple);
     extern void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest);
     extern Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc);
    @@ -740,45 +740,45 @@ extern MinimalTuple minimal_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleD
      *		value, or a pointer into the data area of the tuple).
      *
      *		This must not be used when a system attribute might be requested.
    - *		Furthermore, the passed attnum MUST be valid.  Use heap_getattr()
    + *		Furthermore, the passed attphysnum MUST be valid.  Use heap_getattr()
      *		instead, if in doubt.
      *
      *		This gets called many times, so we macro the cacheable and NULL
      *		lookups, and call nocachegetattr() for the rest.
      */
     static inline Datum
    -fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
    +fastgetattr(HeapTuple tup, int attphysnum, TupleDesc tupleDesc, bool *isnull)
     {
    -	Assert(attnum > 0);
    +	Assert(attphysnum > 0);
     
     	*isnull = false;
     	if (HeapTupleNoNulls(tup))
     	{
     		Form_pg_attribute att;
     
    -		att = TupleDescAttr(tupleDesc, attnum - 1);
    +		att = TupleDescAttr(tupleDesc, attphysnum - 1);
     		if (att->attcacheoff >= 0)
     			return fetchatt(att, (char *) tup->t_data + tup->t_data->t_hoff +
     							att->attcacheoff);
     		else
    -			return nocachegetattr(tup, attnum, tupleDesc);
    +			return nocachegetattr(tup, attphysnum, tupleDesc);
     	}
     	else
     	{
    -		if (att_isnull(attnum - 1, tup->t_data->t_bits))
    +		if (att_isnull(attphysnum - 1, tup->t_data->t_bits))
     		{
     			*isnull = true;
     			return (Datum) NULL;
     		}
     		else
    -			return nocachegetattr(tup, attnum, tupleDesc);
    +			return nocachegetattr(tup, attphysnum, tupleDesc);
     	}
     }
     
     /*
      *	heap_getattr
      *		Extract an attribute of a heap tuple and return it as a Datum.
    - *		This works for either system or user attributes.  The given attnum
    + *		This works for either system or user attributes.  The given attphysnum
      *		is properly range-checked.
      *
      *		If the field in question has a NULL value, we return a zero Datum
    @@ -790,17 +790,17 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
      *
      */
     static inline Datum
    -heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
    +heap_getattr(HeapTuple tup, int attphysnum, TupleDesc tupleDesc, bool *isnull)
     {
    -	if (attnum > 0)
    +	if (attphysnum > 0)
     	{
    -		if (attnum > (int) HeapTupleHeaderGetNatts(tup->t_data))
    -			return getmissingattr(tupleDesc, attnum, isnull);
    +		if (attphysnum > (int) HeapTupleHeaderGetNatts(tup->t_data))
    +			return getmissingattr(tupleDesc, attphysnum, isnull);
     		else
    -			return fastgetattr(tup, attnum, tupleDesc, isnull);
    +			return fastgetattr(tup, attphysnum, tupleDesc, isnull);
     	}
     	else
    -		return heap_getsysattr(tup, attnum, tupleDesc, isnull);
    +		return heap_getsysattr(tup, attphysnum, tupleDesc, isnull);
     }
     #endif							/* FRONTEND */
     
    diff --git a/src/include/access/itup.h b/src/include/access/itup.h
    index 2c8877e991..c31a20d53f 100644
    --- a/src/include/access/itup.h
    +++ b/src/include/access/itup.h
    @@ -97,31 +97,31 @@ typedef IndexAttributeBitMapData * IndexAttributeBitMap;
      *
      * ----------------
      */
    -#define index_getattr(tup, attnum, tupleDesc, isnull) \
    +#define index_getattr(tup, attphysnum, tupleDesc, isnull) \
     ( \
    -	AssertMacro(PointerIsValid(isnull) && (attnum) > 0), \
    +	AssertMacro(PointerIsValid(isnull) && (attphysnum) > 0), \
     	*(isnull) = false, \
     	!IndexTupleHasNulls(tup) ? \
     	( \
    -		TupleDescAttr((tupleDesc), (attnum)-1)->attcacheoff >= 0 ? \
    +		TupleDescAttr((tupleDesc), (attphysnum)-1)->attcacheoff >= 0 ? \
     		( \
    -			fetchatt(TupleDescAttr((tupleDesc), (attnum)-1), \
    +			fetchatt(TupleDescAttr((tupleDesc), (attphysnum)-1), \
     			(char *) (tup) + IndexInfoFindDataOffset((tup)->t_info) \
    -			+ TupleDescAttr((tupleDesc), (attnum)-1)->attcacheoff) \
    +			+ TupleDescAttr((tupleDesc), (attphysnum)-1)->attcacheoff) \
     		) \
     		: \
    -			nocache_index_getattr((tup), (attnum), (tupleDesc)) \
    +			nocache_index_getattr((tup), (attphysnum), (tupleDesc)) \
     	) \
     	: \
     	( \
    -		(att_isnull((attnum)-1, (char *)(tup) + sizeof(IndexTupleData))) ? \
    +		(att_isnull((attphysnum)-1, (char *)(tup) + sizeof(IndexTupleData))) ? \
     		( \
     			*(isnull) = true, \
     			(Datum)NULL \
     		) \
     		: \
     		( \
    -			nocache_index_getattr((tup), (attnum), (tupleDesc)) \
    +			nocache_index_getattr((tup), (attphysnum), (tupleDesc)) \
     		) \
     	) \
     )
    @@ -150,7 +150,7 @@ typedef IndexAttributeBitMapData * IndexAttributeBitMap;
     /* routines in indextuple.c */
     extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor,
     								   Datum *values, bool *isnull);
    -extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
    +extern Datum nocache_index_getattr(IndexTuple tup, int attphysnum,
     								   TupleDesc tupleDesc);
     extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor,
     							   Datum *values, bool *isnull);
    diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
    index 49d4ad560f..cd4c2590f3 100644
    --- a/src/include/bootstrap/bootstrap.h
    +++ b/src/include/bootstrap/bootstrap.h
    @@ -37,7 +37,7 @@ extern void BootstrapModeMain(int argc, char *argv[], bool check_only) pg_attrib
     extern void closerel(char *name);
     extern void boot_openrel(char *name);
     
    -extern void DefineAttr(char *name, char *type, int attnum, int nullness);
    +extern void DefineAttr(char *name, char *type, int attphysnum, int nullness);
     extern void InsertOneTuple(void);
     extern void InsertOneValue(char *value, int i);
     extern void InsertOneNull(int i);
    diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
    index d027075a4c..076fe7ff28 100644
    --- a/src/include/catalog/dependency.h
    +++ b/src/include/catalog/dependency.h
    @@ -220,7 +220,7 @@ extern List *getAutoExtensionsOfObject(Oid classId, Oid objectId);
     
     extern bool sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId);
     extern List *getOwnedSequences(Oid relid);
    -extern Oid	getIdentitySequence(Oid relid, AttrNumber attnum, bool missing_ok);
    +extern Oid	getIdentitySequence(Oid relid, AttrNumber attphysnum, bool missing_ok);
     
     extern Oid	get_index_constraint(Oid indexId);
     
    diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h
    index 07c5b88f0e..69d226dfd6 100644
    --- a/src/include/catalog/heap.h
    +++ b/src/include/catalog/heap.h
    @@ -26,7 +26,7 @@
     
     typedef struct RawColumnDefault
     {
    -	AttrNumber	attnum;			/* attribute to attach default to */
    +	AttrNumber	attphysnum;			/* attribute to attach default to */
     	Node	   *raw_default;	/* default value (untransformed parse tree) */
     	bool		missingMode;	/* true if part of add column processing */
     	char		generated;		/* attgenerated setting */
    @@ -37,7 +37,7 @@ typedef struct CookedConstraint
     	ConstrType	contype;		/* CONSTR_DEFAULT or CONSTR_CHECK */
     	Oid			conoid;			/* constr OID if created, otherwise Invalid */
     	char	   *name;			/* name, or NULL if none */
    -	AttrNumber	attnum;			/* which attr (only for DEFAULT) */
    +	AttrNumber	attphysnum;			/* which attr (only for DEFAULT) */
     	Node	   *expr;			/* transformed default or check expr */
     	bool		skip_validation;	/* skip validation? (only for CHECK) */
     	bool		is_local;		/* constraint has local (non-inherited) def */
    @@ -127,10 +127,10 @@ extern Node *cookDefault(ParseState *pstate,
     extern void DeleteRelationTuple(Oid relid);
     extern void DeleteAttributeTuples(Oid relid);
     extern void DeleteSystemAttributeTuples(Oid relid);
    -extern void RemoveAttributeById(Oid relid, AttrNumber attnum);
    +extern void RemoveAttributeById(Oid relid, AttrNumber attphysnum);
     
     extern void CopyStatistics(Oid fromrelid, Oid torelid);
    -extern void RemoveStatistics(Oid relid, AttrNumber attnum);
    +extern void RemoveStatistics(Oid relid, AttrNumber attphysnum);
     
     extern const FormData_pg_attribute *SystemAttributeDefinition(AttrNumber attno);
     
    diff --git a/src/include/catalog/pg_attrdef.h b/src/include/catalog/pg_attrdef.h
    index a21dd3812b..53373c4d63 100644
    --- a/src/include/catalog/pg_attrdef.h
    +++ b/src/include/catalog/pg_attrdef.h
    @@ -33,7 +33,7 @@ CATALOG(pg_attrdef,2604,AttrDefaultRelationId)
     
     	Oid			adrelid BKI_LOOKUP(pg_class);	/* OID of table containing
     												 * attribute */
    -	int16		adnum;			/* attnum of attribute */
    +	int16		adnum;			/* attphysnum of attribute */
     
     #ifdef CATALOG_VARLEN			/* variable-length fields start here */
     	pg_node_tree adbin BKI_FORCE_NOT_NULL;	/* nodeToString representation of
    @@ -53,18 +53,18 @@ DECLARE_TOAST(pg_attrdef, 2830, 2831);
     DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index, 2656, AttrDefaultIndexId, on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops));
     DECLARE_UNIQUE_INDEX_PKEY(pg_attrdef_oid_index, 2657, AttrDefaultOidIndexId, on pg_attrdef using btree(oid oid_ops));
     
    -DECLARE_FOREIGN_KEY((adrelid, adnum), pg_attribute, (attrelid, attnum));
    +DECLARE_FOREIGN_KEY((adrelid, adnum), pg_attribute, (attrelid, attphysnum));
     
     
    -extern Oid	StoreAttrDefault(Relation rel, AttrNumber attnum,
    +extern Oid	StoreAttrDefault(Relation rel, AttrNumber attphysnum,
     							 Node *expr, bool is_internal,
     							 bool add_column_mode);
    -extern void RemoveAttrDefault(Oid relid, AttrNumber attnum,
    +extern void RemoveAttrDefault(Oid relid, AttrNumber attphysnum,
     							  DropBehavior behavior,
     							  bool complain, bool internal);
     extern void RemoveAttrDefaultById(Oid attrdefId);
     
    -extern Oid	GetAttrDefaultOid(Oid relid, AttrNumber attnum);
    +extern Oid	GetAttrDefaultOid(Oid relid, AttrNumber attphysnum);
     extern ObjectAddress GetAttrDefaultColumnAddress(Oid attrdefoid);
     
     #endif							/* PG_ATTRDEF_H */
    diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
    index 053294c99f..746566eb8d 100644
    --- a/src/include/catalog/pg_attribute.h
    +++ b/src/include/catalog/pg_attribute.h
    @@ -68,7 +68,7 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
     	int16		attlen;
     
     	/*
    -	 * attnum is the "attribute number" for the attribute:	A value that
    +	 * attphysnum is the "attribute number" for the attribute:	A value that
     	 * uniquely identifies this attribute within its class. For user
     	 * attributes, Attribute numbers are greater than 0 and not greater than
     	 * the number of attributes in the class. I.e. if the Class pg_class says
    @@ -78,9 +78,9 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
     	 * System attributes have attribute numbers less than 0 that are unique
     	 * within the class, but not constrained to any particular range.
     	 *
    -	 * Note that (attnum - 1) is often used as the index to an array.
    +	 * Note that (attphysnum - 1) is often used as the index to an array.
     	 */
    -	int16		attnum;
    +	int16		attphysnum;
     
     	/*
     	 * attndims is the declared number of dimensions, if an array type,
    @@ -207,7 +207,7 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
     typedef FormData_pg_attribute *Form_pg_attribute;
     
     DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index, 2658, AttributeRelidNameIndexId, on pg_attribute using btree(attrelid oid_ops, attname name_ops));
    -DECLARE_UNIQUE_INDEX_PKEY(pg_attribute_relid_attnum_index, 2659, AttributeRelidNumIndexId, on pg_attribute using btree(attrelid oid_ops, attnum int2_ops));
    +DECLARE_UNIQUE_INDEX_PKEY(pg_attribute_relid_attphysnum_index, 2659, AttributeRelidPhysNumIndexId, on pg_attribute using btree(attrelid oid_ops, attphysnum int2_ops));
     
     #ifdef EXPOSE_TO_CLIENT_CODE
     
    diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h
    index e7d967f137..39c5c23095 100644
    --- a/src/include/catalog/pg_constraint.h
    +++ b/src/include/catalog/pg_constraint.h
    @@ -173,8 +173,8 @@ DECLARE_UNIQUE_INDEX_PKEY(pg_constraint_oid_index, 2667, ConstraintOidIndexId, o
     DECLARE_INDEX(pg_constraint_conparentid_index, 2579, ConstraintParentIndexId, on pg_constraint using btree(conparentid oid_ops));
     
     /* conkey can contain zero (InvalidAttrNumber) if a whole-row Var is used */
    -DECLARE_ARRAY_FOREIGN_KEY_OPT((conrelid, conkey), pg_attribute, (attrelid, attnum));
    -DECLARE_ARRAY_FOREIGN_KEY((confrelid, confkey), pg_attribute, (attrelid, attnum));
    +DECLARE_ARRAY_FOREIGN_KEY_OPT((conrelid, conkey), pg_attribute, (attrelid, attphysnum));
    +DECLARE_ARRAY_FOREIGN_KEY((confrelid, confkey), pg_attribute, (attrelid, attphysnum));
     
     #ifdef EXPOSE_TO_CLIENT_CODE
     
    diff --git a/src/include/catalog/pg_index.h b/src/include/catalog/pg_index.h
    index f853846ee1..13d4fcb805 100644
    --- a/src/include/catalog/pg_index.h
    +++ b/src/include/catalog/pg_index.h
    @@ -73,7 +73,7 @@ DECLARE_INDEX(pg_index_indrelid_index, 2678, IndexIndrelidIndexId, on pg_index u
     DECLARE_UNIQUE_INDEX_PKEY(pg_index_indexrelid_index, 2679, IndexRelidIndexId, on pg_index using btree(indexrelid oid_ops));
     
     /* indkey can contain zero (InvalidAttrNumber) to represent expressions */
    -DECLARE_ARRAY_FOREIGN_KEY_OPT((indrelid, indkey), pg_attribute, (attrelid, attnum));
    +DECLARE_ARRAY_FOREIGN_KEY_OPT((indrelid, indkey), pg_attribute, (attrelid, attphysnum));
     
     #ifdef EXPOSE_TO_CLIENT_CODE
     
    diff --git a/src/include/catalog/pg_partitioned_table.h b/src/include/catalog/pg_partitioned_table.h
    index 9b78f84cd5..c6da704bf4 100644
    --- a/src/include/catalog/pg_partitioned_table.h
    +++ b/src/include/catalog/pg_partitioned_table.h
    @@ -69,6 +69,6 @@ DECLARE_TOAST(pg_partitioned_table, 4165, 4166);
     DECLARE_UNIQUE_INDEX_PKEY(pg_partitioned_table_partrelid_index, 3351, PartitionedRelidIndexId, on pg_partitioned_table using btree(partrelid oid_ops));
     
     /* partattrs can contain zero (InvalidAttrNumber) to represent expressions */
    -DECLARE_ARRAY_FOREIGN_KEY_OPT((partrelid, partattrs), pg_attribute, (attrelid, attnum));
    +DECLARE_ARRAY_FOREIGN_KEY_OPT((partrelid, partattrs), pg_attribute, (attrelid, attphysnum));
     
     #endif							/* PG_PARTITIONED_TABLE_H */
    diff --git a/src/include/catalog/pg_statistic.h b/src/include/catalog/pg_statistic.h
    index cdf7448139..d63b8dd30f 100644
    --- a/src/include/catalog/pg_statistic.h
    +++ b/src/include/catalog/pg_statistic.h
    @@ -138,7 +138,7 @@ DECLARE_TOAST(pg_statistic, 2840, 2841);
     
     DECLARE_UNIQUE_INDEX_PKEY(pg_statistic_relid_att_inh_index, 2696, StatisticRelidAttnumInhIndexId, on pg_statistic using btree(starelid oid_ops, staattnum int2_ops, stainherit bool_ops));
     
    -DECLARE_FOREIGN_KEY((starelid, staattnum), pg_attribute, (attrelid, attnum));
    +DECLARE_FOREIGN_KEY((starelid, staattnum), pg_attribute, (attrelid, attphysnum));
     
     #ifdef EXPOSE_TO_CLIENT_CODE
     
    diff --git a/src/include/catalog/pg_statistic_ext.h b/src/include/catalog/pg_statistic_ext.h
    index b8520ba923..96b260e34d 100644
    --- a/src/include/catalog/pg_statistic_ext.h
    +++ b/src/include/catalog/pg_statistic_ext.h
    @@ -74,7 +74,7 @@ DECLARE_UNIQUE_INDEX_PKEY(pg_statistic_ext_oid_index, 3380, StatisticExtOidIndex
     DECLARE_UNIQUE_INDEX(pg_statistic_ext_name_index, 3997, StatisticExtNameIndexId, on pg_statistic_ext using btree(stxname name_ops, stxnamespace oid_ops));
     DECLARE_INDEX(pg_statistic_ext_relid_index, 3379, StatisticExtRelidIndexId, on pg_statistic_ext using btree(stxrelid oid_ops));
     
    -DECLARE_ARRAY_FOREIGN_KEY((stxrelid, stxkeys), pg_attribute, (attrelid, attnum));
    +DECLARE_ARRAY_FOREIGN_KEY((stxrelid, stxkeys), pg_attribute, (attrelid, attphysnum));
     
     #ifdef EXPOSE_TO_CLIENT_CODE
     
    diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.h
    index 194277bca5..7036916879 100644
    --- a/src/include/catalog/pg_trigger.h
    +++ b/src/include/catalog/pg_trigger.h
    @@ -85,7 +85,7 @@ DECLARE_INDEX(pg_trigger_tgconstraint_index, 2699, TriggerConstraintIndexId, on
     DECLARE_UNIQUE_INDEX(pg_trigger_tgrelid_tgname_index, 2701, TriggerRelidNameIndexId, on pg_trigger using btree(tgrelid oid_ops, tgname name_ops));
     DECLARE_UNIQUE_INDEX_PKEY(pg_trigger_oid_index, 2702, TriggerOidIndexId, on pg_trigger using btree(oid oid_ops));
     
    -DECLARE_ARRAY_FOREIGN_KEY((tgrelid, tgattr), pg_attribute, (attrelid, attnum));
    +DECLARE_ARRAY_FOREIGN_KEY((tgrelid, tgattr), pg_attribute, (attrelid, attphysnum));
     
     #ifdef EXPOSE_TO_CLIENT_CODE
     
    diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
    index e34db8c93c..709b84bd79 100644
    --- a/src/include/executor/execExpr.h
    +++ b/src/include/executor/execExpr.h
    @@ -301,9 +301,9 @@ typedef struct ExprEvalStep
     		/* for EEOP_INNER/OUTER/SCAN_[SYS]VAR[_FIRST] */
     		struct
     		{
    -			/* attnum is attr number - 1 for regular VAR ... */
    +			/* attphysnum is attr number - 1 for regular VAR ... */
     			/* but it's just the normal (negative) attr number for SYSVAR */
    -			int			attnum;
    +			int			attphysnum;
     			Oid			vartype;	/* type OID of variable */
     		}			var;
     
    @@ -323,7 +323,7 @@ typedef struct ExprEvalStep
     			/* target index in ExprState->resultslot->tts_values/nulls */
     			int			resultnum;
     			/* source attribute number - 1 */
    -			int			attnum;
    +			int			attphysnum;
     		}			assign_var;
     
     		/* for EEOP_ASSIGN_TMP[_MAKE_RO] */
    diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h
    index b2c0c7486c..a49ea6cfef 100644
    --- a/src/include/executor/spi.h
    +++ b/src/include/executor/spi.h
    @@ -161,7 +161,7 @@ extern CachedPlan *SPI_plan_get_cached_plan(SPIPlanPtr plan);
     extern HeapTuple SPI_copytuple(HeapTuple tuple);
     extern HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc);
     extern HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts,
    -								 int *attnum, Datum *Values, const char *Nulls);
    +								 int *attphysnum, Datum *Values, const char *Nulls);
     extern int	SPI_fnumber(TupleDesc tupdesc, const char *fname);
     extern char *SPI_fname(TupleDesc tupdesc, int fnumber);
     extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber);
    diff --git a/src/include/executor/tuptable.h b/src/include/executor/tuptable.h
    index 6306bb6fc6..3b8f0607a0 100644
    --- a/src/include/executor/tuptable.h
    +++ b/src/include/executor/tuptable.h
    @@ -165,7 +165,7 @@ struct TupleTableSlotOps
     	 * to false, if it's not NULL. Throws an error if the slot type does not
     	 * support system attributes.
     	 */
    -	Datum		(*getsysattr) (TupleTableSlot *slot, int attnum, bool *isnull);
    +	Datum		(*getsysattr) (TupleTableSlot *slot, int attphysnum, bool *isnull);
     
     	/*
     	 * Make the contents of the slot solely depend on the slot, and not on
    @@ -328,7 +328,7 @@ extern MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot,
     extern Datum ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot);
     extern void slot_getmissingattrs(TupleTableSlot *slot, int startAttNum,
     								 int lastAttNum);
    -extern void slot_getsomeattrs_int(TupleTableSlot *slot, int attnum);
    +extern void slot_getsomeattrs_int(TupleTableSlot *slot, int attphysnum);
     
     
     #ifndef FRONTEND
    @@ -338,10 +338,10 @@ extern void slot_getsomeattrs_int(TupleTableSlot *slot, int attnum);
      * valid at least up through the attnum'th entry.
      */
     static inline void
    -slot_getsomeattrs(TupleTableSlot *slot, int attnum)
    +slot_getsomeattrs(TupleTableSlot *slot, int attphysnum)
     {
    -	if (slot->tts_nvalid < attnum)
    -		slot_getsomeattrs_int(slot, attnum);
    +	if (slot->tts_nvalid < attphysnum)
    +		slot_getsomeattrs_int(slot, attphysnum);
     }
     
     /*
    @@ -364,31 +364,31 @@ slot_getallattrs(TupleTableSlot *slot)
      * it.
      */
     static inline bool
    -slot_attisnull(TupleTableSlot *slot, int attnum)
    +slot_attisnull(TupleTableSlot *slot, int attphysnum)
     {
    -	AssertArg(attnum > 0);
    +	AssertArg(attphysnum > 0);
     
    -	if (attnum > slot->tts_nvalid)
    -		slot_getsomeattrs(slot, attnum);
    +	if (attphysnum > slot->tts_nvalid)
    +		slot_getsomeattrs(slot, attphysnum);
     
    -	return slot->tts_isnull[attnum - 1];
    +	return slot->tts_isnull[attphysnum - 1];
     }
     
     /*
      * slot_getattr - fetch one attribute of the slot's contents.
      */
     static inline Datum
    -slot_getattr(TupleTableSlot *slot, int attnum,
    +slot_getattr(TupleTableSlot *slot, int attphysnum,
     			 bool *isnull)
     {
    -	AssertArg(attnum > 0);
    +	AssertArg(attphysnum > 0);
     
    -	if (attnum > slot->tts_nvalid)
    -		slot_getsomeattrs(slot, attnum);
    +	if (attphysnum > slot->tts_nvalid)
    +		slot_getsomeattrs(slot, attphysnum);
     
    -	*isnull = slot->tts_isnull[attnum - 1];
    +	*isnull = slot->tts_isnull[attphysnum - 1];
     
    -	return slot->tts_values[attnum - 1];
    +	return slot->tts_values[attphysnum - 1];
     }
     
     /*
    @@ -399,23 +399,23 @@ slot_getattr(TupleTableSlot *slot, int attnum,
      *  the slot type is the one that supports system attributes.
      */
     static inline Datum
    -slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
    +slot_getsysattr(TupleTableSlot *slot, int attphysnum, bool *isnull)
     {
    -	AssertArg(attnum < 0);		/* caller error */
    +	AssertArg(attphysnum < 0);		/* caller error */
     
    -	if (attnum == TableOidAttributeNumber)
    +	if (attphysnum == TableOidAttributeNumber)
     	{
     		*isnull = false;
     		return ObjectIdGetDatum(slot->tts_tableOid);
     	}
    -	else if (attnum == SelfItemPointerAttributeNumber)
    +	else if (attphysnum == SelfItemPointerAttributeNumber)
     	{
     		*isnull = false;
     		return PointerGetDatum(&slot->tts_tid);
     	}
     
     	/* Fetch the system attribute from the underlying tuple. */
    -	return slot->tts_ops->getsysattr(slot, attnum, isnull);
    +	return slot->tts_ops->getsysattr(slot, attphysnum, isnull);
     }
     
     /*
    diff --git a/src/include/foreign/foreign.h b/src/include/foreign/foreign.h
    index 75538110fc..0e28214a86 100644
    --- a/src/include/foreign/foreign.h
    +++ b/src/include/foreign/foreign.h
    @@ -76,7 +76,7 @@ extern ForeignDataWrapper *GetForeignDataWrapperByName(const char *name,
     													   bool missing_ok);
     extern ForeignTable *GetForeignTable(Oid relid);
     
    -extern List *GetForeignColumnOptions(Oid relid, AttrNumber attnum);
    +extern List *GetForeignColumnOptions(Oid relid, AttrNumber attphysnum);
     
     extern Oid	get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok);
     extern Oid	get_foreign_server_oid(const char *servername, bool missing_ok);
    diff --git a/src/include/parser/parsetree.h b/src/include/parser/parsetree.h
    index 3a1afffd18..0aa6de3247 100644
    --- a/src/include/parser/parsetree.h
    +++ b/src/include/parser/parsetree.h
    @@ -35,13 +35,13 @@
      * Given an RTE and an attribute number, return the appropriate
      * variable name or alias for that attribute of that RTE.
      */
    -extern char *get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum);
    +extern char *get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attphysnum);
     
     /*
      * Check whether an attribute of an RTE has been dropped
      */
     extern bool get_rte_attribute_is_dropped(RangeTblEntry *rte,
    -										 AttrNumber attnum);
    +										 AttrNumber attphysnum);
     
     
     /* ----------------
    diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
    index 48f7d72add..a51586f473 100644
    --- a/src/include/utils/acl.h
    +++ b/src/include/utils/acl.h
    @@ -234,9 +234,9 @@ extern void ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivi
     
     extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid);
     
    -extern AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum,
    +extern AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attphysnum,
     									Oid roleid, AclMode mask, AclMaskHow how);
    -extern AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum,
    +extern AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attphysnum,
     										Oid roleid, AclMode mask,
     										AclMaskHow how, bool *is_missing);
     extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
    @@ -267,9 +267,9 @@ extern AclMode pg_foreign_server_aclmask(Oid srv_oid, Oid roleid,
     extern AclMode pg_type_aclmask(Oid type_oid, Oid roleid,
     							   AclMode mask, AclMaskHow how);
     
    -extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
    +extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attphysnum,
     									   Oid roleid, AclMode mode);
    -extern AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum,
    +extern AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attphysnum,
     										   Oid roleid, AclMode mode,
     										   bool *is_missing);
     extern AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid,
    diff --git a/src/include/utils/attoptcache.h b/src/include/utils/attoptcache.h
    index ee37af9500..1042d41503 100644
    --- a/src/include/utils/attoptcache.h
    +++ b/src/include/utils/attoptcache.h
    @@ -23,6 +23,6 @@ typedef struct AttributeOpts
     	float8		n_distinct_inherited;
     } AttributeOpts;
     
    -extern AttributeOpts *get_attribute_options(Oid spcid, int attnum);
    +extern AttributeOpts *get_attribute_options(Oid spcid, int attphysnum);
     
     #endif							/* ATTOPTCACHE_H */
    diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
    index b8dd27d4a9..3f90894219 100644
    --- a/src/include/utils/lsyscache.h
    +++ b/src/include/utils/lsyscache.h
    @@ -62,7 +62,7 @@ typedef struct AttStatsSlot
     } AttStatsSlot;
     
     /* Hook for plugins to get control in get_attavgwidth() */
    -typedef int32 (*get_attavgwidth_hook_type) (Oid relid, AttrNumber attnum);
    +typedef int32 (*get_attavgwidth_hook_type) (Oid relid, AttrNumber attphysnum);
     extern PGDLLIMPORT get_attavgwidth_hook_type get_attavgwidth_hook;
     
     extern bool op_in_opfamily(Oid opno, Oid opfamily);
    @@ -88,14 +88,14 @@ extern bool equality_ops_are_compatible(Oid opno1, Oid opno2);
     extern bool comparison_ops_are_compatible(Oid opno1, Oid opno2);
     extern Oid	get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype,
     							  int16 procnum);
    -extern char *get_attname(Oid relid, AttrNumber attnum, bool missing_ok);
    -extern AttrNumber get_attnum(Oid relid, const char *attname);
    -extern int	get_attstattarget(Oid relid, AttrNumber attnum);
    -extern char get_attgenerated(Oid relid, AttrNumber attnum);
    -extern Oid	get_atttype(Oid relid, AttrNumber attnum);
    -extern void get_atttypetypmodcoll(Oid relid, AttrNumber attnum,
    +extern char *get_attname(Oid relid, AttrNumber attphysnum, bool missing_ok);
    +extern AttrNumber get_attphysnum(Oid relid, const char *attname);
    +extern int	get_attstattarget(Oid relid, AttrNumber attphysnum);
    +extern char get_attgenerated(Oid relid, AttrNumber attphysnum);
    +extern Oid	get_atttype(Oid relid, AttrNumber attphysnum);
    +extern void get_atttypetypmodcoll(Oid relid, AttrNumber attphysnum,
     								  Oid *typid, int32 *typmod, Oid *collid);
    -extern Datum get_attoptions(Oid relid, int16 attnum);
    +extern Datum get_attoptions(Oid relid, int16 attphysnum);
     extern Oid	get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
     extern char *get_collation_name(Oid colloid);
     extern bool get_collation_isdeterministic(Oid colloid);
    @@ -184,7 +184,7 @@ extern const struct SubscriptRoutines *getSubscriptingRoutines(Oid typid,
     extern Oid	getBaseType(Oid typid);
     extern Oid	getBaseTypeAndTypmod(Oid typid, int32 *typmod);
     extern int32 get_typavgwidth(Oid typid, int32 typmod);
    -extern int32 get_attavgwidth(Oid relid, AttrNumber attnum);
    +extern int32 get_attavgwidth(Oid relid, AttrNumber attphysnum);
     extern bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
     							 int reqkind, Oid reqop, int flags);
     extern void free_attstatsslot(AttStatsSlot *sslot);
    diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h
    index c93d8654bb..4733e06849 100644
    --- a/src/include/utils/relcache.h
    +++ b/src/include/utils/relcache.h
    @@ -84,7 +84,7 @@ extern void RelationInitTableAccessMethod(Relation relation);
      * Routines to support ereport() reports of relation-related errors
      */
     extern int	errtable(Relation rel);
    -extern int	errtablecol(Relation rel, int attnum);
    +extern int	errtablecol(Relation rel, int attphysnum);
     extern int	errtablecolname(Relation rel, const char *colname);
     extern int	errtableconstraint(Relation rel, const char *conname);
     
    diff --git a/src/include/utils/selfuncs.h b/src/include/utils/selfuncs.h
    index d485b9bfcd..e7afaa14fc 100644
    --- a/src/include/utils/selfuncs.h
    +++ b/src/include/utils/selfuncs.h
    @@ -136,7 +136,7 @@ typedef struct
     /* Hooks for plugins to get control when we ask for stats */
     typedef bool (*get_relation_stats_hook_type) (PlannerInfo *root,
     											  RangeTblEntry *rte,
    -											  AttrNumber attnum,
    +											  AttrNumber attphysnum,
     											  VariableStatData *vardata);
     extern PGDLLIMPORT get_relation_stats_hook_type get_relation_stats_hook;
     typedef bool (*get_index_stats_hook_type) (PlannerInfo *root,
    diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
    index 4463ea66be..a7c817a72f 100644
    --- a/src/include/utils/syscache.h
    +++ b/src/include/utils/syscache.h
    @@ -38,7 +38,7 @@ enum SysCacheIdentifier
     	AMOPSTRATEGY,
     	AMPROCNUM,
     	ATTNAME,
    -	ATTNUM,
    +	ATTPHYSNUM,
     	AUTHMEMMEMROLE,
     	AUTHMEMROLEMEM,
     	AUTHNAME,
    @@ -151,8 +151,8 @@ extern HeapTuple SearchSysCacheAttName(Oid relid, const char *attname);
     extern HeapTuple SearchSysCacheCopyAttName(Oid relid, const char *attname);
     extern bool SearchSysCacheExistsAttName(Oid relid, const char *attname);
     
    -extern HeapTuple SearchSysCacheAttNum(Oid relid, int16 attnum);
    -extern HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attnum);
    +extern HeapTuple SearchSysCacheAttNum(Oid relid, int16 attphysnum);
    +extern HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attphysnum);
     
     extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup,
     							 AttrNumber attributeNumber, bool *isNull);
    diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
    index 4e6ee1c619..1a09017356 100644
    --- a/src/pl/plpgsql/src/plpgsql.h
    +++ b/src/pl/plpgsql/src/plpgsql.h
    @@ -426,7 +426,7 @@ typedef struct PLpgSQL_recfield
     	int			recparentno;	/* dno of parent record */
     	int			nextfield;		/* dno of next child, or -1 if none */
     	uint64		rectupledescid; /* record's tupledesc ID as of last lookup */
    -	ExpandedRecordFieldInfo finfo;	/* field's attnum and type info */
    +	ExpandedRecordFieldInfo finfo;	/* field's attphysnum and type info */
     	/* if rectupledescid == INVALID_TUPLEDESC_IDENTIFIER, finfo isn't valid */
     } PLpgSQL_recfield;
     
    diff --git a/src/test/modules/brin/expected/summarization-and-inprogress-insertion.out b/src/test/modules/brin/expected/summarization-and-inprogress-insertion.out
    index 2a4755d099..92efe0b6ea 100644
    --- a/src/test/modules/brin/expected/summarization-and-inprogress-insertion.out
    +++ b/src/test/modules/brin/expected/summarization-and-inprogress-insertion.out
    @@ -2,9 +2,9 @@ Parsed test spec with 2 sessions
     
     starting permutation: s2check s1b s2b s1i s2summ s1c s2c s2check
     step s2check: SELECT * FROM brin_page_items(get_raw_page('brinidx', 2), 'brinidx'::regclass);
    -itemoffset|blknum|attnum|allnulls|hasnulls|placeholder|value   
    -----------+------+------+--------+--------+-----------+--------
    -         1|     0|     1|f       |f       |f          |{1 .. 1}
    +itemoffset|blknum|attphysnum|allnulls|hasnulls|placeholder|value   
    +----------+------+----------+--------+--------+-----------+--------
    +         1|     0|         1|f       |f       |f          |{1 .. 1}
     (1 row)
     
     step s1b: BEGIN ISOLATION LEVEL REPEATABLE READ;
    @@ -24,18 +24,18 @@ brin_summarize_new_values
     step s1c: COMMIT;
     step s2c: COMMIT;
     step s2check: SELECT * FROM brin_page_items(get_raw_page('brinidx', 2), 'brinidx'::regclass);
    -itemoffset|blknum|attnum|allnulls|hasnulls|placeholder|value      
    -----------+------+------+--------+--------+-----------+-----------
    -         1|     0|     1|f       |f       |f          |{1 .. 1}   
    -         2|     1|     1|f       |f       |f          |{1 .. 1000}
    +itemoffset|blknum|attphysnum|allnulls|hasnulls|placeholder|value      
    +----------+------+----------+--------+--------+-----------+-----------
    +         1|     0|         1|f       |f       |f          |{1 .. 1}   
    +         2|     1|         1|f       |f       |f          |{1 .. 1000}
     (2 rows)
     
     
     starting permutation: s2check s1b s1i s2vacuum s1c s2check
     step s2check: SELECT * FROM brin_page_items(get_raw_page('brinidx', 2), 'brinidx'::regclass);
    -itemoffset|blknum|attnum|allnulls|hasnulls|placeholder|value   
    -----------+------+------+--------+--------+-----------+--------
    -         1|     0|     1|f       |f       |f          |{1 .. 1}
    +itemoffset|blknum|attphysnum|allnulls|hasnulls|placeholder|value   
    +----------+------+----------+--------+--------+-----------+--------
    +         1|     0|         1|f       |f       |f          |{1 .. 1}
     (1 row)
     
     step s1b: BEGIN ISOLATION LEVEL REPEATABLE READ;
    @@ -43,9 +43,9 @@ step s1i: INSERT INTO brin_iso VALUES (1000);
     step s2vacuum: VACUUM brin_iso;
     step s1c: COMMIT;
     step s2check: SELECT * FROM brin_page_items(get_raw_page('brinidx', 2), 'brinidx'::regclass);
    -itemoffset|blknum|attnum|allnulls|hasnulls|placeholder|value      
    -----------+------+------+--------+--------+-----------+-----------
    -         1|     0|     1|f       |f       |f          |{1 .. 1}   
    -         2|     1|     1|f       |f       |f          |{1 .. 1000}
    +itemoffset|blknum|attphysnum|allnulls|hasnulls|placeholder|value      
    +----------+------+----------+--------+--------+-----------+-----------
    +         1|     0|         1|f       |f       |f          |{1 .. 1}   
    +         2|     1|         1|f       |f       |f          |{1 .. 1000}
     (2 rows)
     
    diff --git a/src/test/modules/test_misc/t/001_constraint_validation.pl b/src/test/modules/test_misc/t/001_constraint_validation.pl
    index 3b9fc66b8e..62ef05dd08 100644
    --- a/src/test/modules/test_misc/t/001_constraint_validation.pl
    +++ b/src/test/modules/test_misc/t/001_constraint_validation.pl
    @@ -209,7 +209,7 @@ run_sql_command(
     	c int,
     	d int,
     	e int,
    -	LIKE list_parted2,  -- a will have attnum = 4
    +	LIKE list_parted2,  -- a will have attphysnum = 4
     	CONSTRAINT check_b CHECK (b IS NULL OR b = \'a\'),
     	CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7)
     	);
    diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
    index 5ede56d9b5..777de22333 100644
    --- a/src/test/regress/expected/alter_table.out
    +++ b/src/test/regress/expected/alter_table.out
    @@ -1746,8 +1746,8 @@ NOTICE:  merging multiple inherited definitions of column "name"
     create table gc1() inherits (c1);
     select relname, attname, attinhcount, attislocal
     from pg_class join pg_attribute on (pg_class.oid = pg_attribute.attrelid)
    -where relname in ('p1','p2','c1','gc1') and attnum > 0 and not attisdropped
    -order by relname, attnum;
    +where relname in ('p1','p2','c1','gc1') and attphysnum > 0 and not attisdropped
    +order by relname, attphysnum;
      relname | attname | attinhcount | attislocal 
     ---------+---------+-------------+------------
      c1      | id      |           1 | f
    @@ -1789,8 +1789,8 @@ alter table dropColumnExists drop column if exists non_existing; --succeed
     NOTICE:  column "non_existing" of relation "dropcolumnexists" does not exist, skipping
     select relname, attname, attinhcount, attislocal
     from pg_class join pg_attribute on (pg_class.oid = pg_attribute.attrelid)
    -where relname in ('p1','p2','c1','gc1') and attnum > 0 and not attisdropped
    -order by relname, attnum;
    +where relname in ('p1','p2','c1','gc1') and attphysnum > 0 and not attisdropped
    +order by relname, attphysnum;
      relname | attname | attinhcount | attislocal 
     ---------+---------+-------------+------------
      c1      | id      |           1 | f
    @@ -1815,8 +1815,8 @@ alter table depth0 add c text;
     NOTICE:  merging definition of column "c" for child "depth1"
     select attrelid::regclass, attname, attinhcount, attislocal
     from pg_attribute
    -where attnum > 0 and attrelid::regclass in ('depth0', 'depth1', 'depth2')
    -order by attrelid::regclass::text, attnum;
    +where attphysnum > 0 and attrelid::regclass in ('depth0', 'depth1', 'depth2')
    +order by attrelid::regclass::text, attphysnum;
      attrelid | attname | attinhcount | attislocal 
     ----------+---------+-------------+------------
      depth0   | c       |           0 | t
    @@ -3915,7 +3915,7 @@ CREATE TABLE part_1 (
     );
     ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (1);
     -- attislocal and conislocal are always false for merged attributes and constraints respectively.
    -SELECT attislocal, attinhcount FROM pg_attribute WHERE attrelid = 'part_1'::regclass AND attnum > 0;
    +SELECT attislocal, attinhcount FROM pg_attribute WHERE attrelid = 'part_1'::regclass AND attphysnum > 0;
      attislocal | attinhcount 
     ------------+-------------
      f          |           1
    @@ -4063,7 +4063,7 @@ CREATE TABLE part_7_a_null (
     	c int,
     	d int,
     	e int,
    -	LIKE list_parted2,  -- 'a' will have attnum = 4
    +	LIKE list_parted2,  -- 'a' will have attphysnum = 4
     	CONSTRAINT check_b CHECK (b IS NULL OR b = 'a'),
     	CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7)
     );
    @@ -4200,7 +4200,7 @@ DROP TABLE not_a_part;
     -- check that, after being detached, attinhcount/coninhcount is dropped to 0 and
     -- attislocal/conislocal is set to true
     ALTER TABLE list_parted2 DETACH PARTITION part_3_4;
    -SELECT attinhcount, attislocal FROM pg_attribute WHERE attrelid = 'part_3_4'::regclass AND attnum > 0;
    +SELECT attinhcount, attislocal FROM pg_attribute WHERE attrelid = 'part_3_4'::regclass AND attphysnum > 0;
      attinhcount | attislocal 
     -------------+------------
                0 | t
    @@ -4359,19 +4359,19 @@ alter table p11 drop a;
     alter table p11 add a int;
     alter table p11 drop a;
     alter table p11 add a int not null;
    --- attnum for key attribute 'a' is different in p, p1, and p11
    -select attrelid::regclass, attname, attnum
    +-- attphysnum for key attribute 'a' is different in p, p1, and p11
    +select attrelid::regclass, attname, attphysnum
     from pg_attribute
     where attname = 'a'
      and (attrelid = 'p'::regclass
        or attrelid = 'p1'::regclass
        or attrelid = 'p11'::regclass)
     order by attrelid::regclass::text;
    - attrelid | attname | attnum 
    -----------+---------+--------
    - p        | a       |      1
    - p1       | a       |      2
    - p11      | a       |      4
    + attrelid | attname | attphysnum 
    +----------+---------+------------
    + p        | a       |          1
    + p1       | a       |          2
    + p11      | a       |          4
     (3 rows)
     
     alter table p1 attach partition p11 for values from (2) to (5);
    diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
    index d55aec3a1d..aef80b4c36 100644
    --- a/src/test/regress/expected/create_index.out
    +++ b/src/test/regress/expected/create_index.out
    @@ -2684,17 +2684,17 @@ SELECT starelid::regclass, count(*) FROM pg_statistic WHERE starelid IN (
     (1 row)
     
     -- attstattarget should remain intact
    -SELECT attrelid::regclass, attnum, attstattarget
    +SELECT attrelid::regclass, attphysnum, attstattarget
       FROM pg_attribute WHERE attrelid IN (
         'concur_exprs_index_expr'::regclass,
         'concur_exprs_index_pred'::regclass,
         'concur_exprs_index_pred_2'::regclass)
    -  ORDER BY attrelid::regclass::text, attnum;
    -         attrelid          | attnum | attstattarget 
    ----------------------------+--------+---------------
    - concur_exprs_index_expr   |      1 |           100
    - concur_exprs_index_pred   |      1 |            -1
    - concur_exprs_index_pred_2 |      1 |            -1
    +  ORDER BY attrelid::regclass::text, attphysnum;
    +         attrelid          | attphysnum | attstattarget 
    +---------------------------+------------+---------------
    + concur_exprs_index_expr   |          1 |           100
    + concur_exprs_index_pred   |          1 |            -1
    + concur_exprs_index_pred_2 |          1 |            -1
     (3 rows)
     
     DROP TABLE concur_exprs_tab;
    diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
    index 4407a017a9..0d93f2c5bb 100644
    --- a/src/test/regress/expected/create_table.out
    +++ b/src/test/regress/expected/create_table.out
    @@ -742,8 +742,8 @@ CREATE TABLE parted (
     CREATE TABLE part_a PARTITION OF parted FOR VALUES IN ('a');
     -- only inherited attributes (never local ones)
     SELECT attname, attislocal, attinhcount FROM pg_attribute
    -  WHERE attrelid = 'part_a'::regclass and attnum > 0
    -  ORDER BY attnum;
    +  WHERE attrelid = 'part_a'::regclass and attphysnum > 0
    +  ORDER BY attphysnum;
      attname | attislocal | attinhcount 
     ---------+------------+-------------
      a       | f          |           1
    diff --git a/src/test/regress/expected/create_type.out b/src/test/regress/expected/create_type.out
    index 0dfc88c1c8..53b998b33f 100644
    --- a/src/test/regress/expected/create_type.out
    +++ b/src/test/regress/expected/create_type.out
    @@ -214,7 +214,7 @@ LINE 1: CREATE TEMP TABLE mytab (foo widget(42,13,7));
                                          ^
     CREATE TEMP TABLE mytab (foo widget(42,13));
     SELECT format_type(atttypid,atttypmod) FROM pg_attribute
    -WHERE attrelid = 'mytab'::regclass AND attnum > 0;
    +WHERE attrelid = 'mytab'::regclass AND attphysnum > 0;
       format_type  
     ---------------
      widget(42,13)
    diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out
    index da26f083bc..584630b8a7 100644
    --- a/src/test/regress/expected/foreign_key.out
    +++ b/src/test/regress/expected/foreign_key.out
    @@ -1466,7 +1466,7 @@ explain (costs off) delete from t1 where a = 1;
     (10 rows)
     
     delete from t1 where a = 1;
    --- Test a primary key with attributes located in later attnum positions
    +-- Test a primary key with attributes located in later attphysnum positions
     -- compared to the fk attributes.
     create table pktable2 (a int, b int, c int, d int, e int, primary key (d, e));
     create table fktable2 (d int, e int, foreign key (d, e) references pktable2);
    diff --git a/src/test/regress/expected/indexing.out b/src/test/regress/expected/indexing.out
    index 193f780191..d0d117a5c7 100644
    --- a/src/test/regress/expected/indexing.out
    +++ b/src/test/regress/expected/indexing.out
    @@ -815,18 +815,18 @@ Partition of: idxpart FOR VALUES FROM (0) TO (1000)
     Indexes:
         "idxpart1_col_keep_idx" btree (col_keep)
     
    -select attrelid::regclass, attname, attnum from pg_attribute
    -  where attrelid::regclass::text like 'idxpart%' and attnum > 0
    -  order by attrelid::regclass, attnum;
    -       attrelid        |           attname            | attnum 
    ------------------------+------------------------------+--------
    - idxpart1              | ........pg.dropped.1........ |      1
    - idxpart1              | ........pg.dropped.2........ |      2
    - idxpart1              | col_keep                     |      3
    - idxpart1              | ........pg.dropped.4........ |      4
    - idxpart1_col_keep_idx | col_keep                     |      1
    - idxpart               | col_keep                     |      1
    - idxpart_col_keep_idx  | col_keep                     |      1
    +select attrelid::regclass, attname, attphysnum from pg_attribute
    +  where attrelid::regclass::text like 'idxpart%' and attphysnum > 0
    +  order by attrelid::regclass, attphysnum;
    +       attrelid        |           attname            | attphysnum 
    +-----------------------+------------------------------+------------
    + idxpart1              | ........pg.dropped.1........ |          1
    + idxpart1              | ........pg.dropped.2........ |          2
    + idxpart1              | col_keep                     |          3
    + idxpart1              | ........pg.dropped.4........ |          4
    + idxpart1_col_keep_idx | col_keep                     |          1
    + idxpart               | col_keep                     |          1
    + idxpart_col_keep_idx  | col_keep                     |          1
     (7 rows)
     
     drop table idxpart;
    @@ -858,18 +858,18 @@ Partition of: idxpart FOR VALUES FROM (0) TO (1000)
     Indexes:
         "idxpart1_col_keep_idx" btree (col_keep)
     
    -select attrelid::regclass, attname, attnum from pg_attribute
    -  where attrelid::regclass::text like 'idxpart%' and attnum > 0
    -  order by attrelid::regclass, attnum;
    -       attrelid        |           attname            | attnum 
    ------------------------+------------------------------+--------
    - idxpart               | ........pg.dropped.1........ |      1
    - idxpart               | ........pg.dropped.2........ |      2
    - idxpart               | col_keep                     |      3
    - idxpart               | ........pg.dropped.4........ |      4
    - idxpart1              | col_keep                     |      1
    - idxpart1_col_keep_idx | col_keep                     |      1
    - idxpart_col_keep_idx  | col_keep                     |      1
    +select attrelid::regclass, attname, attphysnum from pg_attribute
    +  where attrelid::regclass::text like 'idxpart%' and attphysnum > 0
    +  order by attrelid::regclass, attphysnum;
    +       attrelid        |           attname            | attphysnum 
    +-----------------------+------------------------------+------------
    + idxpart               | ........pg.dropped.1........ |          1
    + idxpart               | ........pg.dropped.2........ |          2
    + idxpart               | col_keep                     |          3
    + idxpart               | ........pg.dropped.4........ |          4
    + idxpart1              | col_keep                     |          1
    + idxpart1_col_keep_idx | col_keep                     |          1
    + idxpart_col_keep_idx  | col_keep                     |          1
     (7 rows)
     
     drop table idxpart;
    diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out
    index 2d49e765de..84bc012f30 100644
    --- a/src/test/regress/expected/inherit.out
    +++ b/src/test/regress/expected/inherit.out
    @@ -1106,7 +1106,7 @@ SELECT a.attrelid::regclass, a.attname, a.attinhcount, e.expected
       FROM (SELECT inhrelid, count(*) AS expected FROM pg_inherits
             WHERE inhparent IN (SELECT inhrelid FROM r) GROUP BY inhrelid) e
       JOIN pg_attribute a ON e.inhrelid = a.attrelid WHERE NOT attislocal
    -  ORDER BY a.attrelid::regclass::name, a.attnum;
    +  ORDER BY a.attrelid::regclass::name, a.attphysnum;
      attrelid | attname | attinhcount | expected 
     ----------+---------+-------------+----------
      inht2    | aaaa    |           1 |        1
    diff --git a/src/test/regress/expected/insert.out b/src/test/regress/expected/insert.out
    index dd4354fc7d..491d7ff28e 100644
    --- a/src/test/regress/expected/insert.out
    +++ b/src/test/regress/expected/insert.out
    @@ -497,19 +497,19 @@ alter table mlparted11 drop a;
     alter table mlparted11 add a int;
     alter table mlparted11 drop a;
     alter table mlparted11 add a int not null;
    --- attnum for key attribute 'a' is different in mlparted, mlparted1, and mlparted11
    -select attrelid::regclass, attname, attnum
    +-- attphysnum for key attribute 'a' is different in mlparted, mlparted1, and mlparted11
    +select attrelid::regclass, attname, attphysnum
     from pg_attribute
     where attname = 'a'
      and (attrelid = 'mlparted'::regclass
        or attrelid = 'mlparted1'::regclass
        or attrelid = 'mlparted11'::regclass)
     order by attrelid::regclass::text;
    -  attrelid  | attname | attnum 
    -------------+---------+--------
    - mlparted   | a       |      1
    - mlparted1  | a       |      2
    - mlparted11 | a       |      4
    +  attrelid  | attname | attphysnum 
    +------------+---------+------------
    + mlparted   | a       |          1
    + mlparted1  | a       |          2
    + mlparted11 | a       |          4
     (3 rows)
     
     alter table mlparted1 attach partition mlparted11 for values from (2) to (5);
    diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
    index 2538bd6a79..cab82b3093 100644
    --- a/src/test/regress/expected/join.out
    +++ b/src/test/regress/expected/join.out
    @@ -4944,8 +4944,8 @@ HINT:  Perhaps you meant to reference the column "t1.unique1" or the column "t2.
     --
     select atts.relid::regclass, s.* from pg_stats s join
         pg_attribute a on s.attname = a.attname and s.tablename =
    -    a.attrelid::regclass::text join (select unnest(indkey) attnum,
    -    indexrelid from pg_index i) atts on atts.attnum = a.attnum where
    +    a.attrelid::regclass::text join (select unnest(indkey) attphysnum,
    +    indexrelid from pg_index i) atts on atts.attphysnum = a.attphysnum where
         schemaname != 'pg_catalog';
     ERROR:  column atts.relid does not exist
     LINE 1: select atts.relid::regclass, s.* from pg_stats s join
    diff --git a/src/test/regress/expected/oidjoins.out b/src/test/regress/expected/oidjoins.out
    index 215eb899be..5acd051618 100644
    --- a/src/test/regress/expected/oidjoins.out
    +++ b/src/test/regress/expected/oidjoins.out
    @@ -83,7 +83,7 @@ NOTICE:  checking pg_class {reltablespace} => pg_tablespace {oid}
     NOTICE:  checking pg_class {reltoastrelid} => pg_class {oid}
     NOTICE:  checking pg_class {relrewrite} => pg_class {oid}
     NOTICE:  checking pg_attrdef {adrelid} => pg_class {oid}
    -NOTICE:  checking pg_attrdef {adrelid,adnum} => pg_attribute {attrelid,attnum}
    +NOTICE:  checking pg_attrdef {adrelid,adnum} => pg_attribute {attrelid,attphysnum}
     NOTICE:  checking pg_constraint {connamespace} => pg_namespace {oid}
     NOTICE:  checking pg_constraint {conrelid} => pg_class {oid}
     NOTICE:  checking pg_constraint {contypid} => pg_type {oid}
    @@ -94,15 +94,15 @@ NOTICE:  checking pg_constraint {conpfeqop} => pg_operator {oid}
     NOTICE:  checking pg_constraint {conppeqop} => pg_operator {oid}
     NOTICE:  checking pg_constraint {conffeqop} => pg_operator {oid}
     NOTICE:  checking pg_constraint {conexclop} => pg_operator {oid}
    -NOTICE:  checking pg_constraint {conrelid,conkey} => pg_attribute {attrelid,attnum}
    -NOTICE:  checking pg_constraint {confrelid,confkey} => pg_attribute {attrelid,attnum}
    +NOTICE:  checking pg_constraint {conrelid,conkey} => pg_attribute {attrelid,attphysnum}
    +NOTICE:  checking pg_constraint {confrelid,confkey} => pg_attribute {attrelid,attphysnum}
     NOTICE:  checking pg_inherits {inhrelid} => pg_class {oid}
     NOTICE:  checking pg_inherits {inhparent} => pg_class {oid}
     NOTICE:  checking pg_index {indexrelid} => pg_class {oid}
     NOTICE:  checking pg_index {indrelid} => pg_class {oid}
     NOTICE:  checking pg_index {indcollation} => pg_collation {oid}
     NOTICE:  checking pg_index {indclass} => pg_opclass {oid}
    -NOTICE:  checking pg_index {indrelid,indkey} => pg_attribute {attrelid,attnum}
    +NOTICE:  checking pg_index {indrelid,indkey} => pg_attribute {attrelid,attphysnum}
     NOTICE:  checking pg_operator {oprnamespace} => pg_namespace {oid}
     NOTICE:  checking pg_operator {oprowner} => pg_authid {oid}
     NOTICE:  checking pg_operator {oprleft} => pg_type {oid}
    @@ -162,11 +162,11 @@ NOTICE:  checking pg_statistic {stacoll2} => pg_collation {oid}
     NOTICE:  checking pg_statistic {stacoll3} => pg_collation {oid}
     NOTICE:  checking pg_statistic {stacoll4} => pg_collation {oid}
     NOTICE:  checking pg_statistic {stacoll5} => pg_collation {oid}
    -NOTICE:  checking pg_statistic {starelid,staattnum} => pg_attribute {attrelid,attnum}
    +NOTICE:  checking pg_statistic {starelid,staattnum} => pg_attribute {attrelid,attphysnum}
     NOTICE:  checking pg_statistic_ext {stxrelid} => pg_class {oid}
     NOTICE:  checking pg_statistic_ext {stxnamespace} => pg_namespace {oid}
     NOTICE:  checking pg_statistic_ext {stxowner} => pg_authid {oid}
    -NOTICE:  checking pg_statistic_ext {stxrelid,stxkeys} => pg_attribute {attrelid,attnum}
    +NOTICE:  checking pg_statistic_ext {stxrelid,stxkeys} => pg_attribute {attrelid,attphysnum}
     NOTICE:  checking pg_statistic_ext_data {stxoid} => pg_statistic_ext {oid}
     NOTICE:  checking pg_rewrite {ev_class} => pg_class {oid}
     NOTICE:  checking pg_trigger {tgrelid} => pg_class {oid}
    @@ -175,7 +175,7 @@ NOTICE:  checking pg_trigger {tgfoid} => pg_proc {oid}
     NOTICE:  checking pg_trigger {tgconstrrelid} => pg_class {oid}
     NOTICE:  checking pg_trigger {tgconstrindid} => pg_class {oid}
     NOTICE:  checking pg_trigger {tgconstraint} => pg_constraint {oid}
    -NOTICE:  checking pg_trigger {tgrelid,tgattr} => pg_attribute {attrelid,attnum}
    +NOTICE:  checking pg_trigger {tgrelid,tgattr} => pg_attribute {attrelid,attphysnum}
     NOTICE:  checking pg_event_trigger {evtowner} => pg_authid {oid}
     NOTICE:  checking pg_event_trigger {evtfoid} => pg_proc {oid}
     NOTICE:  checking pg_description {classoid} => pg_class {oid}
    @@ -243,7 +243,7 @@ NOTICE:  checking pg_partitioned_table {partrelid} => pg_class {oid}
     NOTICE:  checking pg_partitioned_table {partdefid} => pg_class {oid}
     NOTICE:  checking pg_partitioned_table {partclass} => pg_opclass {oid}
     NOTICE:  checking pg_partitioned_table {partcollation} => pg_collation {oid}
    -NOTICE:  checking pg_partitioned_table {partrelid,partattrs} => pg_attribute {attrelid,attnum}
    +NOTICE:  checking pg_partitioned_table {partrelid,partattrs} => pg_attribute {attrelid,attphysnum}
     NOTICE:  checking pg_range {rngtypid} => pg_type {oid}
     NOTICE:  checking pg_range {rngsubtype} => pg_type {oid}
     NOTICE:  checking pg_range {rngmultitypid} => pg_type {oid}
    diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
    index 86d755aa44..12e883ff79 100644
    --- a/src/test/regress/expected/opr_sanity.out
    +++ b/src/test/regress/expected/opr_sanity.out
    @@ -2216,7 +2216,7 @@ FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey,
           FROM pg_index) ss,
           pg_attribute a,
           pg_opclass opc
    -WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND
    +WHERE a.attrelid = indrelid AND a.attphysnum = ikey AND opc.oid = iclass AND
           (NOT binary_coercible(atttypid, opcintype) OR icoll != attcollation);
      indexrelid | indrelid | attname | atttypid | opcname 
     ------------+----------+---------+----------+---------
    @@ -2232,7 +2232,7 @@ FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey,
           WHERE indrelid < 16384) ss,
           pg_attribute a,
           pg_opclass opc
    -WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND
    +WHERE a.attrelid = indrelid AND a.attphysnum = ikey AND opc.oid = iclass AND
           (opcintype != atttypid OR icoll != attcollation)
     ORDER BY 1;
             indexrelid        |   indrelid   | attname  | atttypid | opcname 
    diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
    index 60acbd1241..195fa9f287 100644
    --- a/src/test/regress/expected/psql.out
    +++ b/src/test/regress/expected/psql.out
    @@ -241,8 +241,8 @@ SELECT 3 AS x, 'Hello', 4 AS y, true AS "dirty\name" \gdesc \g
     create temporary table gexec_test(a int, b text, c date, d float);
     select format('create index on gexec_test(%I)', attname)
     from pg_attribute
    -where attrelid = 'gexec_test'::regclass and attnum > 0
    -order by attnum
    +where attrelid = 'gexec_test'::regclass and attphysnum > 0
    +order by attphysnum
     \gexec
     create index on gexec_test(a)
     create index on gexec_test(b)
    diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
    index fc3cde3226..fcf522dad8 100644
    --- a/src/test/regress/expected/rules.out
    +++ b/src/test/regress/expected/rules.out
    @@ -1438,14 +1438,14 @@ pg_prepared_xacts| SELECT p.transaction,
     pg_publication_tables| SELECT p.pubname,
         n.nspname AS schemaname,
         c.relname AS tablename,
    -    ( SELECT array_agg(a.attname ORDER BY a.attnum) AS array_agg
    +    ( SELECT array_agg(a.attname ORDER BY a.attphysnum) AS array_agg
                FROM (unnest(
                     CASE
                         WHEN (gpt.attrs IS NOT NULL) THEN (gpt.attrs)::integer[]
                         ELSE ( SELECT array_agg(g.g) AS array_agg
                            FROM generate_series(1, (c.relnatts)::integer) g(g))
                     END) k(k)
    -             JOIN pg_attribute a ON (((a.attrelid = gpt.relid) AND (a.attnum = k.k))))) AS attnames,
    +             JOIN pg_attribute a ON (((a.attrelid = gpt.relid) AND (a.attphysnum = k.k))))) AS attnames,
         pg_get_expr(gpt.qual, gpt.relid) AS rowfilter
        FROM pg_publication p,
         LATERAL pg_get_publication_tables((p.pubname)::text) gpt(relid, attrs, qual),
    @@ -1534,7 +1534,7 @@ UNION ALL
         l.label
        FROM (((pg_seclabel l
          JOIN pg_class rel ON (((l.classoid = rel.tableoid) AND (l.objoid = rel.oid))))
    -     JOIN pg_attribute att ON (((rel.oid = att.attrelid) AND (l.objsubid = att.attnum))))
    +     JOIN pg_attribute att ON (((rel.oid = att.attrelid) AND (l.objsubid = att.attphysnum))))
          JOIN pg_namespace nsp ON ((rel.relnamespace = nsp.oid)))
       WHERE (l.objsubid <> 0)
     UNION ALL
    @@ -2428,17 +2428,17 @@ pg_stats| SELECT n.nspname AS schemaname,
             END AS elem_count_histogram
        FROM (((pg_statistic s
          JOIN pg_class c ON ((c.oid = s.starelid)))
    -     JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum))))
    +     JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attphysnum = s.staattnum))))
          LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
    -  WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
    +  WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attphysnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
     pg_stats_ext| SELECT cn.nspname AS schemaname,
         c.relname AS tablename,
         sn.nspname AS statistics_schemaname,
         s.stxname AS statistics_name,
         pg_get_userbyid(s.stxowner) AS statistics_owner,
    -    ( SELECT array_agg(a.attname ORDER BY a.attnum) AS array_agg
    +    ( SELECT array_agg(a.attname ORDER BY a.attphysnum) AS array_agg
                FROM (unnest(s.stxkeys) k(k)
    -             JOIN pg_attribute a ON (((a.attrelid = s.stxrelid) AND (a.attnum = k.k))))) AS attnames,
    +             JOIN pg_attribute a ON (((a.attrelid = s.stxrelid) AND (a.attphysnum = k.k))))) AS attnames,
         pg_get_statisticsobjdef_expressions(s.oid) AS exprs,
         s.stxkind AS kinds,
         sd.stxdinherit AS inherited,
    @@ -2460,8 +2460,8 @@ pg_stats_ext| SELECT cn.nspname AS schemaname,
                FROM pg_mcv_list_items(sd.stxdmcv) pg_mcv_list_items(index, "values", nulls, frequency, base_frequency)) m ON ((sd.stxdmcv IS NOT NULL)))
       WHERE ((NOT (EXISTS ( SELECT 1
                FROM (unnest(s.stxkeys) k(k)
    -             JOIN pg_attribute a ON (((a.attrelid = s.stxrelid) AND (a.attnum = k.k))))
    -          WHERE (NOT has_column_privilege(c.oid, a.attnum, 'select'::text))))) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
    +             JOIN pg_attribute a ON (((a.attrelid = s.stxrelid) AND (a.attphysnum = k.k))))
    +          WHERE (NOT has_column_privilege(c.oid, a.attphysnum, 'select'::text))))) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid))));
     pg_stats_ext_exprs| SELECT cn.nspname AS schemaname,
         c.relname AS tablename,
         sn.nspname AS statistics_schemaname,
    diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out
    index c5c675b750..7714c49e2f 100644
    --- a/src/test/regress/expected/sanity_check.out
    +++ b/src/test/regress/expected/sanity_check.out
    @@ -10,7 +10,7 @@ SELECT relname, nspname
      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 indkey[0] = a.attphysnum AND indnatts = 1
                          AND indisunique AND indimmediate);
      relname | nspname 
     ---------+---------
    @@ -39,8 +39,8 @@ WITH check_columns AS (
        SELECT t.oid
         FROM pg_type t JOIN pg_attribute pa ON t.oid = pa.atttypid
         WHERE pa.attrelid = a.attrelid AND
    -          pa.attnum > 0 AND pa.attnum < a.attnum
    -    ORDER BY pa.attnum) AS coltypes
    +          pa.attphysnum > 0 AND pa.attphysnum < a.attphysnum
    +    ORDER BY pa.attphysnum) AS coltypes
      FROM pg_attribute a JOIN pg_class c ON c.oid = attrelid
       JOIN pg_namespace n ON c.relnamespace = n.oid
      WHERE attalign = 'd' AND relkind = 'r' AND
    diff --git a/src/test/regress/expected/type_sanity.out b/src/test/regress/expected/type_sanity.out
    index d3ac08c9ee..51fcda3e6f 100644
    --- a/src/test/regress/expected/type_sanity.out
    +++ b/src/test/regress/expected/type_sanity.out
    @@ -578,17 +578,17 @@ WHERE pc.relkind IN ('r', 't', 'm') and
     -- Look for illegal values in pg_attribute fields
     SELECT a1.attrelid, a1.attname
     FROM pg_attribute as a1
    -WHERE a1.attrelid = 0 OR a1.atttypid = 0 OR a1.attnum = 0 OR
    +WHERE a1.attrelid = 0 OR a1.atttypid = 0 OR a1.attphysnum = 0 OR
         a1.attcacheoff != -1 OR a1.attinhcount < 0 OR
         (a1.attinhcount = 0 AND NOT a1.attislocal);
      attrelid | attname 
     ----------+---------
     (0 rows)
     
    --- Cross-check attnum against parent relation
    +-- Cross-check attphysnum against parent relation
     SELECT a1.attrelid, a1.attname, c1.oid, c1.relname
     FROM pg_attribute AS a1, pg_class AS c1
    -WHERE a1.attrelid = c1.oid AND a1.attnum > c1.relnatts;
    +WHERE a1.attrelid = c1.oid AND a1.attphysnum > c1.relnatts;
      attrelid | attname | oid | relname 
     ----------+---------+-----+---------
     (0 rows)
    @@ -598,7 +598,7 @@ WHERE a1.attrelid = c1.oid AND a1.attnum > c1.relnatts;
     SELECT c1.oid, c1.relname
     FROM pg_class AS c1
     WHERE c1.relnatts != (SELECT count(*) FROM pg_attribute AS a1
    -                      WHERE a1.attrelid = c1.oid AND a1.attnum > 0);
    +                      WHERE a1.attrelid = c1.oid AND a1.attphysnum > 0);
      oid | relname 
     -----+---------
     (0 rows)
    @@ -765,7 +765,7 @@ SELECT oid, typname, typtype, typelem, typarray
         AND NOT EXISTS (SELECT 1
                         FROM pg_attribute a
                         WHERE a.atttypid=t.oid AND
    -                          a.attnum > 0 AND
    +                          a.attphysnum > 0 AND
                               a.attrelid='tab_core_types'::regclass);
      oid | typname | typtype | typelem | typarray 
     -----+---------+---------+---------+----------
    diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
    index ba3532a51e..f34c8474b4 100644
    --- a/src/test/regress/regress.c
    +++ b/src/test/regress/regress.c
    @@ -272,7 +272,7 @@ ttdummy(PG_FUNCTION_ARGS)
     	TriggerData *trigdata = (TriggerData *) fcinfo->context;
     	Trigger    *trigger;		/* to get trigger name */
     	char	  **args;			/* arguments */
    -	int			attnum[2];		/* fnumbers of start/stop columns */
    +	int			attphysnum[2];		/* fnumbers of start/stop columns */
     	Datum		oldon,
     				oldoff;
     	Datum		newon,
    @@ -325,29 +325,29 @@ ttdummy(PG_FUNCTION_ARGS)
     
     	for (i = 0; i < 2; i++)
     	{
    -		attnum[i] = SPI_fnumber(tupdesc, args[i]);
    -		if (attnum[i] <= 0)
    +		attphysnum[i] = SPI_fnumber(tupdesc, args[i]);
    +		if (attphysnum[i] <= 0)
     			elog(ERROR, "ttdummy (%s): there is no attribute %s",
     				 relname, args[i]);
    -		if (SPI_gettypeid(tupdesc, attnum[i]) != INT4OID)
    +		if (SPI_gettypeid(tupdesc, attphysnum[i]) != INT4OID)
     			elog(ERROR, "ttdummy (%s): attribute %s must be of integer type",
     				 relname, args[i]);
     	}
     
    -	oldon = SPI_getbinval(trigtuple, tupdesc, attnum[0], &isnull);
    +	oldon = SPI_getbinval(trigtuple, tupdesc, attphysnum[0], &isnull);
     	if (isnull)
     		elog(ERROR, "ttdummy (%s): %s must be NOT NULL", relname, args[0]);
     
    -	oldoff = SPI_getbinval(trigtuple, tupdesc, attnum[1], &isnull);
    +	oldoff = SPI_getbinval(trigtuple, tupdesc, attphysnum[1], &isnull);
     	if (isnull)
     		elog(ERROR, "ttdummy (%s): %s must be NOT NULL", relname, args[1]);
     
     	if (newtuple != NULL)		/* UPDATE */
     	{
    -		newon = SPI_getbinval(newtuple, tupdesc, attnum[0], &isnull);
    +		newon = SPI_getbinval(newtuple, tupdesc, attphysnum[0], &isnull);
     		if (isnull)
     			elog(ERROR, "ttdummy (%s): %s must be NOT NULL", relname, args[0]);
    -		newoff = SPI_getbinval(newtuple, tupdesc, attnum[1], &isnull);
    +		newoff = SPI_getbinval(newtuple, tupdesc, attphysnum[1], &isnull);
     		if (isnull)
     			elog(ERROR, "ttdummy (%s): %s must be NOT NULL", relname, args[1]);
     
    @@ -390,16 +390,16 @@ ttdummy(PG_FUNCTION_ARGS)
     	/* change date column(s) */
     	if (newtuple)				/* UPDATE */
     	{
    -		cvals[attnum[0] - 1] = newoff;	/* start_date eq current date */
    -		cnulls[attnum[0] - 1] = ' ';
    -		cvals[attnum[1] - 1] = TTDUMMY_INFINITY;	/* stop_date eq INFINITY */
    -		cnulls[attnum[1] - 1] = ' ';
    +		cvals[attphysnum[0] - 1] = newoff;	/* start_date eq current date */
    +		cnulls[attphysnum[0] - 1] = ' ';
    +		cvals[attphysnum[1] - 1] = TTDUMMY_INFINITY;	/* stop_date eq INFINITY */
    +		cnulls[attphysnum[1] - 1] = ' ';
     	}
     	else
     		/* DELETE */
     	{
    -		cvals[attnum[1] - 1] = newoff;	/* stop_date eq current date */
    -		cnulls[attnum[1] - 1] = ' ';
    +		cvals[attphysnum[1] - 1] = newoff;	/* stop_date eq current date */
    +		cnulls[attphysnum[1] - 1] = ' ';
     	}
     
     	/* if there is no plan ... */
    @@ -442,7 +442,7 @@ ttdummy(PG_FUNCTION_ARGS)
     
     	/* Tuple to return to upper Executor ... */
     	if (newtuple)				/* UPDATE */
    -		rettuple = SPI_modifytuple(rel, trigtuple, 1, &(attnum[1]), &newoff, NULL);
    +		rettuple = SPI_modifytuple(rel, trigtuple, 1, &(attphysnum[1]), &newoff, NULL);
     	else						/* DELETE */
     		rettuple = trigtuple;
     
    diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
    index 52001e3135..6784da0f4c 100644
    --- a/src/test/regress/sql/alter_table.sql
    +++ b/src/test/regress/sql/alter_table.sql
    @@ -1250,8 +1250,8 @@ create table gc1() inherits (c1);
     
     select relname, attname, attinhcount, attislocal
     from pg_class join pg_attribute on (pg_class.oid = pg_attribute.attrelid)
    -where relname in ('p1','p2','c1','gc1') and attnum > 0 and not attisdropped
    -order by relname, attnum;
    +where relname in ('p1','p2','c1','gc1') and attphysnum > 0 and not attisdropped
    +order by relname, attphysnum;
     
     -- should work
     alter table only p1 drop column name;
    @@ -1273,8 +1273,8 @@ alter table dropColumnExists drop column if exists non_existing; --succeed
     
     select relname, attname, attinhcount, attislocal
     from pg_class join pg_attribute on (pg_class.oid = pg_attribute.attrelid)
    -where relname in ('p1','p2','c1','gc1') and attnum > 0 and not attisdropped
    -order by relname, attnum;
    +where relname in ('p1','p2','c1','gc1') and attphysnum > 0 and not attisdropped
    +order by relname, attphysnum;
     
     drop table p1, p2 cascade;
     
    @@ -1287,8 +1287,8 @@ alter table depth0 add c text;
     
     select attrelid::regclass, attname, attinhcount, attislocal
     from pg_attribute
    -where attnum > 0 and attrelid::regclass in ('depth0', 'depth1', 'depth2')
    -order by attrelid::regclass::text, attnum;
    +where attphysnum > 0 and attrelid::regclass in ('depth0', 'depth1', 'depth2')
    +order by attrelid::regclass::text, attphysnum;
     
     -- test renumbering of child-table columns in inherited operations
     
    @@ -2434,7 +2434,7 @@ CREATE TABLE part_1 (
     );
     ALTER TABLE list_parted ATTACH PARTITION part_1 FOR VALUES IN (1);
     -- attislocal and conislocal are always false for merged attributes and constraints respectively.
    -SELECT attislocal, attinhcount FROM pg_attribute WHERE attrelid = 'part_1'::regclass AND attnum > 0;
    +SELECT attislocal, attinhcount FROM pg_attribute WHERE attrelid = 'part_1'::regclass AND attphysnum > 0;
     SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_1'::regclass AND conname = 'check_a';
     
     -- check that the new partition won't overlap with an existing partition
    @@ -2580,7 +2580,7 @@ CREATE TABLE part_7_a_null (
     	c int,
     	d int,
     	e int,
    -	LIKE list_parted2,  -- 'a' will have attnum = 4
    +	LIKE list_parted2,  -- 'a' will have attphysnum = 4
     	CONSTRAINT check_b CHECK (b IS NULL OR b = 'a'),
     	CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7)
     );
    @@ -2707,7 +2707,7 @@ DROP TABLE not_a_part;
     -- check that, after being detached, attinhcount/coninhcount is dropped to 0 and
     -- attislocal/conislocal is set to true
     ALTER TABLE list_parted2 DETACH PARTITION part_3_4;
    -SELECT attinhcount, attislocal FROM pg_attribute WHERE attrelid = 'part_3_4'::regclass AND attnum > 0;
    +SELECT attinhcount, attislocal FROM pg_attribute WHERE attrelid = 'part_3_4'::regclass AND attphysnum > 0;
     SELECT coninhcount, conislocal FROM pg_constraint WHERE conrelid = 'part_3_4'::regclass AND conname = 'check_a';
     DROP TABLE part_3_4;
     
    @@ -2816,8 +2816,8 @@ alter table p11 drop a;
     alter table p11 add a int;
     alter table p11 drop a;
     alter table p11 add a int not null;
    --- attnum for key attribute 'a' is different in p, p1, and p11
    -select attrelid::regclass, attname, attnum
    +-- attphysnum for key attribute 'a' is different in p, p1, and p11
    +select attrelid::regclass, attname, attphysnum
     from pg_attribute
     where attname = 'a'
      and (attrelid = 'p'::regclass
    diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql
    index d8fded3d93..c2b0f58c6b 100644
    --- a/src/test/regress/sql/create_index.sql
    +++ b/src/test/regress/sql/create_index.sql
    @@ -1140,12 +1140,12 @@ SELECT starelid::regclass, count(*) FROM pg_statistic WHERE starelid IN (
       'concur_exprs_index_pred_2'::regclass)
       GROUP BY starelid ORDER BY starelid::regclass::text;
     -- attstattarget should remain intact
    -SELECT attrelid::regclass, attnum, attstattarget
    +SELECT attrelid::regclass, attphysnum, attstattarget
       FROM pg_attribute WHERE attrelid IN (
         'concur_exprs_index_expr'::regclass,
         'concur_exprs_index_pred'::regclass,
         'concur_exprs_index_pred_2'::regclass)
    -  ORDER BY attrelid::regclass::text, attnum;
    +  ORDER BY attrelid::regclass::text, attphysnum;
     DROP TABLE concur_exprs_tab;
     
     -- Temporary tables and on-commit actions, where CONCURRENTLY is ignored.
    diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql
    index 5175f404f7..b1d935c0fe 100644
    --- a/src/test/regress/sql/create_table.sql
    +++ b/src/test/regress/sql/create_table.sql
    @@ -513,8 +513,8 @@ CREATE TABLE part_a PARTITION OF parted FOR VALUES IN ('a');
     
     -- only inherited attributes (never local ones)
     SELECT attname, attislocal, attinhcount FROM pg_attribute
    -  WHERE attrelid = 'part_a'::regclass and attnum > 0
    -  ORDER BY attnum;
    +  WHERE attrelid = 'part_a'::regclass and attphysnum > 0
    +  ORDER BY attphysnum;
     
     -- able to specify column default, column constraint, and table constraint
     
    diff --git a/src/test/regress/sql/create_type.sql b/src/test/regress/sql/create_type.sql
    index c6fc4f9029..017484ec65 100644
    --- a/src/test/regress/sql/create_type.sql
    +++ b/src/test/regress/sql/create_type.sql
    @@ -180,7 +180,7 @@ CREATE TEMP TABLE mytab (foo widget(42,13,7));     -- should fail
     CREATE TEMP TABLE mytab (foo widget(42,13));
     
     SELECT format_type(atttypid,atttypmod) FROM pg_attribute
    -WHERE attrelid = 'mytab'::regclass AND attnum > 0;
    +WHERE attrelid = 'mytab'::regclass AND attphysnum > 0;
     
     -- might as well exercise the widget type while we're here
     INSERT INTO mytab VALUES ('(1,2,3)'), ('(-44,5.5,12)');
    diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql
    index 725a59a525..6a1118098a 100644
    --- a/src/test/regress/sql/foreign_key.sql
    +++ b/src/test/regress/sql/foreign_key.sql
    @@ -1087,7 +1087,7 @@ create rule r1 as on delete to t1 do delete from t2 where t2.b = old.a;
     explain (costs off) delete from t1 where a = 1;
     delete from t1 where a = 1;
     
    --- Test a primary key with attributes located in later attnum positions
    +-- Test a primary key with attributes located in later attphysnum positions
     -- compared to the fk attributes.
     create table pktable2 (a int, b int, c int, d int, e int, primary key (d, e));
     create table fktable2 (d int, e int, foreign key (d, e) references pktable2);
    diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql
    index 42f398b67c..5370452cb2 100644
    --- a/src/test/regress/sql/indexing.sql
    +++ b/src/test/regress/sql/indexing.sql
    @@ -423,9 +423,9 @@ create index on idxpart (col_keep);
     alter table idxpart attach partition idxpart1 for values from (0) to (1000);
     \d idxpart
     \d idxpart1
    -select attrelid::regclass, attname, attnum from pg_attribute
    -  where attrelid::regclass::text like 'idxpart%' and attnum > 0
    -  order by attrelid::regclass, attnum;
    +select attrelid::regclass, attname, attphysnum from pg_attribute
    +  where attrelid::regclass::text like 'idxpart%' and attphysnum > 0
    +  order by attrelid::regclass, attphysnum;
     drop table idxpart;
     
     -- Column number mapping: dropped columns in the parent table
    @@ -439,9 +439,9 @@ create index on idxpart (col_keep);
     alter table idxpart attach partition idxpart1 for values from (0) to (1000);
     \d idxpart
     \d idxpart1
    -select attrelid::regclass, attname, attnum from pg_attribute
    -  where attrelid::regclass::text like 'idxpart%' and attnum > 0
    -  order by attrelid::regclass, attnum;
    +select attrelid::regclass, attname, attphysnum from pg_attribute
    +  where attrelid::regclass::text like 'idxpart%' and attphysnum > 0
    +  order by attrelid::regclass, attphysnum;
     drop table idxpart;
     
     --
    diff --git a/src/test/regress/sql/inherit.sql b/src/test/regress/sql/inherit.sql
    index 195aedb5ff..8075f622b6 100644
    --- a/src/test/regress/sql/inherit.sql
    +++ b/src/test/regress/sql/inherit.sql
    @@ -375,7 +375,7 @@ SELECT a.attrelid::regclass, a.attname, a.attinhcount, e.expected
       FROM (SELECT inhrelid, count(*) AS expected FROM pg_inherits
             WHERE inhparent IN (SELECT inhrelid FROM r) GROUP BY inhrelid) e
       JOIN pg_attribute a ON e.inhrelid = a.attrelid WHERE NOT attislocal
    -  ORDER BY a.attrelid::regclass::name, a.attnum;
    +  ORDER BY a.attrelid::regclass::name, a.attphysnum;
     
     DROP TABLE inht1, inhs1 CASCADE;
     
    diff --git a/src/test/regress/sql/insert.sql b/src/test/regress/sql/insert.sql
    index bdcffd0314..5ca1483716 100644
    --- a/src/test/regress/sql/insert.sql
    +++ b/src/test/regress/sql/insert.sql
    @@ -299,8 +299,8 @@ alter table mlparted11 drop a;
     alter table mlparted11 add a int;
     alter table mlparted11 drop a;
     alter table mlparted11 add a int not null;
    --- attnum for key attribute 'a' is different in mlparted, mlparted1, and mlparted11
    -select attrelid::regclass, attname, attnum
    +-- attphysnum for key attribute 'a' is different in mlparted, mlparted1, and mlparted11
    +select attrelid::regclass, attname, attphysnum
     from pg_attribute
     where attname = 'a'
      and (attrelid = 'mlparted'::regclass
    diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
    index a27a72086e..397f2add63 100644
    --- a/src/test/regress/sql/join.sql
    +++ b/src/test/regress/sql/join.sql
    @@ -1770,8 +1770,8 @@ select uunique1 from
     
     select atts.relid::regclass, s.* from pg_stats s join
         pg_attribute a on s.attname = a.attname and s.tablename =
    -    a.attrelid::regclass::text join (select unnest(indkey) attnum,
    -    indexrelid from pg_index i) atts on atts.attnum = a.attnum where
    +    a.attrelid::regclass::text join (select unnest(indkey) attphysnum,
    +    indexrelid from pg_index i) atts on atts.attphysnum = a.attphysnum where
         schemaname != 'pg_catalog';
     
     --
    diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
    index 63fe114fed..5aae345792 100644
    --- a/src/test/regress/sql/opr_sanity.sql
    +++ b/src/test/regress/sql/opr_sanity.sql
    @@ -1353,7 +1353,7 @@ FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey,
           FROM pg_index) ss,
           pg_attribute a,
           pg_opclass opc
    -WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND
    +WHERE a.attrelid = indrelid AND a.attphysnum = ikey AND opc.oid = iclass AND
           (NOT binary_coercible(atttypid, opcintype) OR icoll != attcollation);
     
     -- For system catalogs, be even tighter: nearly all indexes should be
    @@ -1367,7 +1367,7 @@ FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey,
           WHERE indrelid < 16384) ss,
           pg_attribute a,
           pg_opclass opc
    -WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND
    +WHERE a.attrelid = indrelid AND a.attphysnum = ikey AND opc.oid = iclass AND
           (opcintype != atttypid OR icoll != attcollation)
     ORDER BY 1;
     
    diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql
    index 1149c6a839..4fcb86d67c 100644
    --- a/src/test/regress/sql/psql.sql
    +++ b/src/test/regress/sql/psql.sql
    @@ -124,8 +124,8 @@ SELECT 3 AS x, 'Hello', 4 AS y, true AS "dirty\name" \gdesc \g
     create temporary table gexec_test(a int, b text, c date, d float);
     select format('create index on gexec_test(%I)', attname)
     from pg_attribute
    -where attrelid = 'gexec_test'::regclass and attnum > 0
    -order by attnum
    +where attrelid = 'gexec_test'::regclass and attphysnum > 0
    +order by attphysnum
     \gexec
     
     -- \gexec should work in FETCH_COUNT mode too
    diff --git a/src/test/regress/sql/sanity_check.sql b/src/test/regress/sql/sanity_check.sql
    index 7f338d191c..67d6b076b7 100644
    --- a/src/test/regress/sql/sanity_check.sql
    +++ b/src/test/regress/sql/sanity_check.sql
    @@ -11,7 +11,7 @@ SELECT relname, nspname
      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 indkey[0] = a.attphysnum AND indnatts = 1
                          AND indisunique AND indimmediate);
     
     -- check that relations without storage don't have relfilenode
    @@ -34,8 +34,8 @@ WITH check_columns AS (
        SELECT t.oid
         FROM pg_type t JOIN pg_attribute pa ON t.oid = pa.atttypid
         WHERE pa.attrelid = a.attrelid AND
    -          pa.attnum > 0 AND pa.attnum < a.attnum
    -    ORDER BY pa.attnum) AS coltypes
    +          pa.attphysnum > 0 AND pa.attphysnum < a.attphysnum
    +    ORDER BY pa.attphysnum) AS coltypes
      FROM pg_attribute a JOIN pg_class c ON c.oid = attrelid
       JOIN pg_namespace n ON c.relnamespace = n.oid
      WHERE attalign = 'd' AND relkind = 'r' AND
    diff --git a/src/test/regress/sql/type_sanity.sql b/src/test/regress/sql/type_sanity.sql
    index 5edc1f1f6e..fedd8790ac 100644
    --- a/src/test/regress/sql/type_sanity.sql
    +++ b/src/test/regress/sql/type_sanity.sql
    @@ -420,15 +420,15 @@ WHERE pc.relkind IN ('r', 't', 'm') and
     
     SELECT a1.attrelid, a1.attname
     FROM pg_attribute as a1
    -WHERE a1.attrelid = 0 OR a1.atttypid = 0 OR a1.attnum = 0 OR
    +WHERE a1.attrelid = 0 OR a1.atttypid = 0 OR a1.attphysnum = 0 OR
         a1.attcacheoff != -1 OR a1.attinhcount < 0 OR
         (a1.attinhcount = 0 AND NOT a1.attislocal);
     
    --- Cross-check attnum against parent relation
    +-- Cross-check attphysnum against parent relation
     
     SELECT a1.attrelid, a1.attname, c1.oid, c1.relname
     FROM pg_attribute AS a1, pg_class AS c1
    -WHERE a1.attrelid = c1.oid AND a1.attnum > c1.relnatts;
    +WHERE a1.attrelid = c1.oid AND a1.attphysnum > c1.relnatts;
     
     -- Detect missing pg_attribute entries: should have as many non-system
     -- attributes as parent relation expects
    @@ -436,7 +436,7 @@ WHERE a1.attrelid = c1.oid AND a1.attnum > c1.relnatts;
     SELECT c1.oid, c1.relname
     FROM pg_class AS c1
     WHERE c1.relnatts != (SELECT count(*) FROM pg_attribute AS a1
    -                      WHERE a1.attrelid = c1.oid AND a1.attnum > 0);
    +                      WHERE a1.attrelid = c1.oid AND a1.attphysnum > 0);
     
     -- Cross-check against pg_type entry
     -- NOTE: we allow attstorage to be 'plain' even when typstorage is not;
    @@ -588,5 +588,5 @@ SELECT oid, typname, typtype, typelem, typarray
         AND NOT EXISTS (SELECT 1
                         FROM pg_attribute a
                         WHERE a.atttypid=t.oid AND
    -                          a.attnum > 0 AND
    +                          a.attphysnum > 0 AND
                               a.attrelid='tab_core_types'::regclass);
    diff --git a/src/tutorial/syscat.source b/src/tutorial/syscat.source
    index 6458c32372..9aa7a6e999 100644
    --- a/src/tutorial/syscat.source
    +++ b/src/tutorial/syscat.source
    @@ -57,7 +57,7 @@ SELECT n.nspname AS schema_name,
       WHERE bc.relnamespace = n.oid
          and i.indrelid = bc.oid
          and i.indexrelid = ic.oid
    -     and i.indkey[0] = a.attnum
    +     and i.indkey[0] = a.attphysnum
          and i.indnatts = 1
          and a.attrelid = bc.oid
       ORDER BY schema_name, class_name, index_name, attname;
    @@ -74,7 +74,7 @@ SELECT n.nspname, c.relname, a.attname, format_type(t.oid, null) as typname
         and c.relkind = 'r'     -- no indices
         and n.nspname not like 'pg\_%' -- no catalogs
         and n.nspname != 'information_schema' -- no information_schema
    -    and a.attnum > 0        -- no system att's
    +    and a.attphysnum > 0        -- no system att's
         and not a.attisdropped   -- no dropped columns
         and a.attrelid = c.oid
         and a.atttypid = t.oid
    -- 
    2.33.1
    
    
    --niuvl3z5xzutv25e
    Content-Type: text/plain; charset=us-ascii
    Content-Disposition: attachment;
    	filename="v1-0002-WIP-Handle-logical-attnum.patch"