This allows the compiler / linker to mark affected pages as read-only.
There's a fair number of pre-requisite changes, to allow the const
properly be propagated. Most of consts were already required for
correctness anyway, just not represented on the type-level.  Arguably
we could be more aggressive in using consts in related code, but..
This requires using a few of the types underlying typedefs that
removes pointers (e.g. const NameData *) as declaring the typedefed
type constant doesn't have the same meaning (it makes the variable
const, not what it points to).
Discussion: https://postgr.es/m/
20181015200754.7y7zfuzsoux2c4ya@alap3.anarazel.de
 
  * fixed-size portion of the structure anyway.
  */
 
-static FormData_pg_attribute a1 = {
+static const FormData_pg_attribute a1 = {
        .attname = {"ctid"},
        .atttypid = TIDOID,
        .attlen = sizeof(ItemPointerData),
        .attislocal = true,
 };
 
-static FormData_pg_attribute a2 = {
+static const FormData_pg_attribute a2 = {
        .attname = {"oid"},
        .atttypid = OIDOID,
        .attlen = sizeof(Oid),
        .attislocal = true,
 };
 
-static FormData_pg_attribute a3 = {
+static const FormData_pg_attribute a3 = {
        .attname = {"xmin"},
        .atttypid = XIDOID,
        .attlen = sizeof(TransactionId),
        .attislocal = true,
 };
 
-static FormData_pg_attribute a4 = {
+static const FormData_pg_attribute a4 = {
        .attname = {"cmin"},
        .atttypid = CIDOID,
        .attlen = sizeof(CommandId),
        .attislocal = true,
 };
 
-static FormData_pg_attribute a5 = {
+static const FormData_pg_attribute a5 = {
        .attname = {"xmax"},
        .atttypid = XIDOID,
        .attlen = sizeof(TransactionId),
        .attislocal = true,
 };
 
-static FormData_pg_attribute a6 = {
+static const FormData_pg_attribute a6 = {
        .attname = {"cmax"},
        .atttypid = CIDOID,
        .attlen = sizeof(CommandId),
  * table of a particular class/type. In any case table is still the word
  * used in SQL.
  */
-static FormData_pg_attribute a7 = {
+static const FormData_pg_attribute a7 = {
        .attname = {"tableoid"},
        .atttypid = OIDOID,
        .attlen = sizeof(Oid),
        .attislocal = true,
 };
 
-static const Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
+static const FormData_pg_attribute *SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
 
 /*
  * This function returns a Form_pg_attribute pointer for a system attribute.
  * Note that we elog if the presented attno is invalid, which would only
  * happen if there's a problem upstream.
  */
-Form_pg_attribute
+const FormData_pg_attribute *
 SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
 {
        if (attno >= 0 || attno < -(int) lengthof(SysAtt))
  * If the given name is a system attribute name, return a Form_pg_attribute
  * pointer for a prototype definition.  If not, return NULL.
  */
-Form_pg_attribute
+const FormData_pg_attribute *
 SystemAttributeByName(const char *attname, bool relhasoids)
 {
        int                     j;
 
        for (j = 0; j < (int) lengthof(SysAtt); j++)
        {
-               Form_pg_attribute att = SysAtt[j];
+               const FormData_pg_attribute *att = SysAtt[j];
 
                if (relhasoids || att->attnum != ObjectIdAttributeNumber)
                {
 
                if (atnum != 0)
                {
                        /* Simple index column */
-                       Form_pg_attribute from;
+                       const FormData_pg_attribute *from;
 
                        if (atnum < 0)
                        {
 
 SPI_fnumber(TupleDesc tupdesc, const char *fname)
 {
        int                     res;
-       Form_pg_attribute sysatt;
+       const FormData_pg_attribute *sysatt;
 
        for (res = 0; res < tupdesc->natts; res++)
        {
 char *
 SPI_fname(TupleDesc tupdesc, int fnumber)
 {
-       Form_pg_attribute att;
+       const FormData_pg_attribute *att;
 
        SPI_result = 0;
 
 
                if (indexkey != 0)
                {
                        /* simple column */
-                       Form_pg_attribute att_tup;
+                       const FormData_pg_attribute *att_tup;
 
                        if (indexkey < 0)
                                att_tup = SystemAttributeDefinition(indexkey,
 
 static int
 specialAttNum(const char *attname)
 {
-       Form_pg_attribute sysatt;
+       const FormData_pg_attribute *sysatt;
 
        sysatt = SystemAttributeByName(attname,
                                                                   true /* "oid" will be accepted */ );
  *     heap_open()'ed.  Use the cache version get_atttype()
  *     for access to non-opened relations.
  */
-Name
+const NameData *
 attnumAttName(Relation rd, int attid)
 {
        if (attid <= 0)
        {
-               Form_pg_attribute sysatt;
+               const FormData_pg_attribute *sysatt;
 
                sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
                return &sysatt->attname;
 {
        if (attid <= 0)
        {
-               Form_pg_attribute sysatt;
+               const FormData_pg_attribute *sysatt;
 
                sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
                return sysatt->atttypid;
 
                for (i = 0; i < index_form->indnatts; i++)
                {
                        int16           attnum = index_form->indkey.values[i];
-                       Form_pg_attribute attform;
+                       const FormData_pg_attribute *attform;
                        char       *attname;
                        Oid                     defopclass;
 
 
        TupleDesc       tupdesc;
        int                     fno;
        Form_pg_attribute attr;
+       const FormData_pg_attribute *sysattr;
 
        tupdesc = expanded_record_get_tupdesc(erh);
 
        }
 
        /* How about system attributes? */
-       attr = SystemAttributeByName(fieldname, tupdesc->tdhasoid);
-       if (attr != NULL)
+       sysattr = SystemAttributeByName(fieldname, tupdesc->tdhasoid);
+       if (sysattr != NULL)
        {
-               finfo->fnumber = attr->attnum;
-               finfo->ftypeid = attr->atttypid;
-               finfo->ftypmod = attr->atttypmod;
-               finfo->fcollation = attr->attcollation;
+               finfo->fnumber = sysattr->attnum;
+               finfo->ftypeid = sysattr->atttypid;
+               finfo->ftypmod = sysattr->atttypmod;
+               finfo->fcollation = sysattr->attcollation;
                return true;
        }
 
 
 /* (see char.c for comparison/operation routines) */
 
 int
-namecpy(Name n1, Name n2)
+namecpy(Name n1, const NameData *n2)
 {
        if (!n1 || !n2)
                return -1;
 
 extern void RemoveAttrDefaultById(Oid attrdefId);
 extern void RemoveStatistics(Oid relid, AttrNumber attnum);
 
-extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno,
+extern const FormData_pg_attribute *SystemAttributeDefinition(AttrNumber attno,
                                                  bool relhasoids);
 
-extern Form_pg_attribute SystemAttributeByName(const char *attname,
+extern const FormData_pg_attribute *SystemAttributeByName(const char *attname,
                                          bool relhasoids);
 
 extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind,
 
 extern List *expandRelAttrs(ParseState *pstate, RangeTblEntry *rte,
                           int rtindex, int sublevels_up, int location);
 extern int     attnameAttNum(Relation rd, const char *attname, bool sysColOK);
-extern Name attnumAttName(Relation rd, int attid);
+extern const NameData *attnumAttName(Relation rd, int attid);
 extern Oid     attnumTypeId(Relation rd, int attid);
 extern Oid     attnumCollationId(Relation rd, int attid);
 extern bool isQueryUsingTempRelation(Query *query);
 
 extern int2vector *buildint2vector(const int16 *int2s, int n);
 
 /* name.c */
-extern int     namecpy(Name n1, Name n2);
+extern int     namecpy(Name n1, const NameData *n2);
 extern int     namestrcpy(Name name, const char *str);
 extern int     namestrcmp(Name name, const char *str);