From f3b421da5f4addc95812b9db05a24972b8fd9739 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 21 Dec 2016 12:00:00 -0500
Subject: [PATCH] Reorder pg_sequence columns to avoid alignment issue

On AIX, doubles are aligned at 4 bytes, but int64 is aligned at 8 bytes.
Our code assumes that doubles have alignment that can also be applied to
int64, but that fails in this case.  One effect is that
heap_form_tuple() writes tuples in a different layout than
Form_pg_sequence expects.

Rather than rewrite the whole alignment code, work around the issue by
reordering the columns in pg_sequence so that the first int64 column
naturally comes out at an 8-byte boundary.
---
 doc/src/sgml/catalogs.sgml        | 14 +++++++-------
 src/backend/commands/sequence.c   |  4 ++--
 src/include/catalog/catversion.h  |  2 +-
 src/include/catalog/pg_sequence.h | 14 +++++++-------
 4 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 7a7bbde390b..493050618df 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -5627,6 +5627,13 @@
       <entry>The OID of the <structname>pg_class</> entry for this sequence</entry>
      </row>
 
+     <row>
+      <entry><structfield>seqcycle</structfield></entry>
+      <entry><type>bool</type></entry>
+      <entry></entry>
+      <entry>Whether the sequence cycles</entry>
+     </row>
+
      <row>
       <entry><structfield>seqstart</structfield></entry>
       <entry><type>int8</type></entry>
@@ -5661,13 +5668,6 @@
       <entry></entry>
       <entry>Cache size of the sequence</entry>
      </row>
-
-     <row>
-      <entry><structfield>seqcycle</structfield></entry>
-      <entry><type>bool</type></entry>
-      <entry></entry>
-      <entry>Whether the sequence cycles</entry>
-     </row>
     </tbody>
    </tgroup>
   </table>
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index cdd32bc17e0..668d82771a8 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -227,12 +227,12 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
 	memset(pgs_nulls, 0, sizeof(pgs_nulls));
 
 	pgs_values[Anum_pg_sequence_seqrelid - 1] = ObjectIdGetDatum(seqoid);
+	pgs_values[Anum_pg_sequence_seqcycle - 1] = BoolGetDatum(seqform.seqcycle);
 	pgs_values[Anum_pg_sequence_seqstart - 1] = Int64GetDatumFast(seqform.seqstart);
 	pgs_values[Anum_pg_sequence_seqincrement - 1] = Int64GetDatumFast(seqform.seqincrement);
 	pgs_values[Anum_pg_sequence_seqmax - 1] = Int64GetDatumFast(seqform.seqmax);
 	pgs_values[Anum_pg_sequence_seqmin - 1] = Int64GetDatumFast(seqform.seqmin);
 	pgs_values[Anum_pg_sequence_seqcache - 1] = Int64GetDatumFast(seqform.seqcache);
-	pgs_values[Anum_pg_sequence_seqcycle - 1] = BoolGetDatum(seqform.seqcycle);
 
 	tuple = heap_form_tuple(tupDesc, pgs_values, pgs_nulls);
 	simple_heap_insert(rel, tuple);
@@ -622,11 +622,11 @@ nextval_internal(Oid relid)
 	if (!HeapTupleIsValid(pgstuple))
 		elog(ERROR, "cache lookup failed for sequence %u", relid);
 	pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
+	cycle = pgsform->seqcycle;
 	incby = pgsform->seqincrement;
 	maxv = pgsform->seqmax;
 	minv = pgsform->seqmin;
 	cache = pgsform->seqcache;
-	cycle = pgsform->seqcycle;
 	ReleaseSysCache(pgstuple);
 
 	/* lock page' buffer and read tuple */
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 5779f0d617f..7d15189ead1 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	201612201
+#define CATALOG_VERSION_NO	201612202
 
 #endif
diff --git a/src/include/catalog/pg_sequence.h b/src/include/catalog/pg_sequence.h
index 3bcda6bef17..350b286e457 100644
--- a/src/include/catalog/pg_sequence.h
+++ b/src/include/catalog/pg_sequence.h
@@ -8,23 +8,23 @@
 CATALOG(pg_sequence,2224) BKI_WITHOUT_OIDS
 {
 	Oid			seqrelid;
+	bool		seqcycle;
 	int64		seqstart;
 	int64		seqincrement;
 	int64		seqmax;
 	int64		seqmin;
 	int64		seqcache;
-	bool		seqcycle;
 } FormData_pg_sequence;
 
 typedef FormData_pg_sequence *Form_pg_sequence;
 
 #define Natts_pg_sequence				7
 #define Anum_pg_sequence_seqrelid		1
-#define Anum_pg_sequence_seqstart		2
-#define Anum_pg_sequence_seqincrement	3
-#define Anum_pg_sequence_seqmax			4
-#define Anum_pg_sequence_seqmin			5
-#define Anum_pg_sequence_seqcache		6
-#define Anum_pg_sequence_seqcycle		7
+#define Anum_pg_sequence_seqcycle		2
+#define Anum_pg_sequence_seqstart		3
+#define Anum_pg_sequence_seqincrement	4
+#define Anum_pg_sequence_seqmax			5
+#define Anum_pg_sequence_seqmin			6
+#define Anum_pg_sequence_seqcache		7
 
 #endif	/* PG_SEQUENCE_H */
-- 
GitLab