From 198b1cd44e98da1924d391014193fa48362f282a Mon Sep 17 00:00:00 2001
From: "Paul A. Jungwirth" <pj@illuminatedcomputing.com>
Date: Fri, 15 Mar 2024 10:51:55 -0700
Subject: [PATCH v28 3/9] Don't infer PERIOD on PK side of temporal FK

---
 doc/src/sgml/ref/create_table.sgml            |  3 +-
 src/backend/commands/tablecmds.c              | 41 ++++++-------
 .../regress/expected/without_overlaps.out     | 61 +++++++++----------
 src/test/regress/sql/without_overlaps.sql     | 58 ++++++++----------
 4 files changed, 77 insertions(+), 86 deletions(-)

diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index eaf3c4b705a..e4778a4079e 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -1167,7 +1167,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
       column(s) of some row of the referenced table.  If the <replaceable
       class="parameter">refcolumn</replaceable> list is omitted, the
       primary key of the <replaceable class="parameter">reftable</replaceable>
-      is used.  Otherwise, the <replaceable class="parameter">refcolumn</replaceable>
+      is used (omitting any part declared with <literal>WITHOUT OVERLAPS</literal>).
+      Otherwise, the <replaceable class="parameter">refcolumn</replaceable>
       list must refer to the columns of a non-deferrable unique or primary key
       constraint or be the columns of a non-partial unique index.
      </para>
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index cfd06e94aae..9de519ea6e5 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -386,7 +386,7 @@ static int	transformColumnNameList(Oid relId, List *colList,
 static int	transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
 									   List **attnamelist,
 									   int16 *attnums, Oid *atttypids,
-									   Oid *opclasses, bool *pk_period);
+									   Oid *opclasses);
 static Oid	transformFkeyCheckAttrs(Relation pkrel,
 									int numattrs, int16 *attnums,
 									bool with_period, Oid *opclasses);
@@ -9819,7 +9819,6 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
 	Oid			ffeqoperators[INDEX_MAX_KEYS] = {0};
 	int16		fkdelsetcols[INDEX_MAX_KEYS] = {0};
 	bool		with_period;
-	bool		pk_with_period;
 	int			i;
 	int			numfks,
 				numpks,
@@ -9921,6 +9920,16 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_FOREIGN_KEY),
 					errmsg("foreign key uses PERIOD on the referenced table but not the referencing table")));
+		/*
+		 * We never infer a PERIOD on the PK side
+		 * (Cf. 11.8 syntax rule 4b of the standard),
+		 * so if we don't have one already we won't ever get one.
+		 */
+		if (!fkconstraint->pk_with_period)
+			ereport(ERROR,
+					(errcode(ERRCODE_INVALID_FOREIGN_KEY),
+					errmsg("foreign key uses PERIOD on the referencing table but not the referenced table")));
+
 	}
 
 	numfkdelsetcols = transformColumnNameList(RelationGetRelid(rel),
@@ -9941,13 +9950,7 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		numpks = transformFkeyGetPrimaryKey(pkrel, &indexOid,
 											&fkconstraint->pk_attrs,
 											pkattnum, pktypoid,
-											opclasses, &pk_with_period);
-
-		/* If the primary key uses WITHOUT OVERLAPS, the fk must use PERIOD */
-		if (pk_with_period && !fkconstraint->fk_with_period)
-			ereport(ERROR,
-					(errcode(ERRCODE_INVALID_FOREIGN_KEY),
-					errmsg("foreign key uses PERIOD on the referenced table but not the referencing table")));
+											opclasses);
 	}
 	else
 	{
@@ -9955,15 +9958,6 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
 										 fkconstraint->pk_attrs,
 										 pkattnum, pktypoid);
 
-		if (with_period)
-		{
-			if (!fkconstraint->pk_with_period)
-				/* Since we got pk_attrs, one should be a period. */
-				ereport(ERROR,
-						(errcode(ERRCODE_INVALID_FOREIGN_KEY),
-						errmsg("foreign key uses PERIOD on the referencing table but not the referenced table")));
-		}
-
 		/* Look for an index matching the column list */
 		indexOid = transformFkeyCheckAttrs(pkrel, numpks, pkattnum,
 										   with_period, opclasses);
@@ -12141,7 +12135,7 @@ static int
 transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
 						   List **attnamelist,
 						   int16 *attnums, Oid *atttypids,
-						   Oid *opclasses, bool *pk_period)
+						   Oid *opclasses)
 {
 	List	   *indexoidlist;
 	ListCell   *indexoidscan;
@@ -12212,6 +12206,13 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
 	{
 		int			pkattno = indexStruct->indkey.values[i];
 
+		/*
+		 * We must omit WITHOUT OVERLAPs parts of the key per the SQL standard 11.8 syntax rule 4b.
+		 * This should cause an error downstream if the FK uses PERIOD---and also if it doesn't!
+		 */
+		if (indexStruct->indisexclusion && i == indexStruct->indnatts - 1)
+			break; /* don't include this item in the number of attributes returned */
+
 		attnums[i] = pkattno;
 		atttypids[i] = attnumTypeId(pkrel, pkattno);
 		opclasses[i] = indclass->values[i];
@@ -12219,8 +12220,6 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
 							   makeString(pstrdup(NameStr(*attnumAttName(pkrel, pkattno)))));
 	}
 
-	*pk_period = (indexStruct->indisexclusion);
-
 	ReleaseSysCache(indexTuple);
 
 	return i;
diff --git a/src/test/regress/expected/without_overlaps.out b/src/test/regress/expected/without_overlaps.out
index ea1a2a4c6c9..cdc55395133 100644
--- a/src/test/regress/expected/without_overlaps.out
+++ b/src/test/regress/expected/without_overlaps.out
@@ -467,7 +467,7 @@ CREATE TABLE temporal_fk_rng2rng (
 	CONSTRAINT temporal_fk_rng2rng_fk FOREIGN KEY (parent_id, valid_at)
 		REFERENCES temporal_rng
 );
-ERROR:  foreign key uses PERIOD on the referenced table but not the referencing table
+ERROR:  number of referencing and referenced columns for foreign key disagree
 -- (parent_id, PERIOD valid_at) REFERENCES (id)
 CREATE TABLE temporal_fk_rng2rng (
 	id int4range,
@@ -489,6 +489,7 @@ CREATE TABLE temporal_fk_rng2rng (
 );
 ERROR:  foreign key uses PERIOD on the referenced table but not the referencing table
 -- with inferred PK on the referenced table:
+-- (This is not permitted by the SQL standard. See 11.8 syntax rule 4b.)
 CREATE TABLE temporal_fk_rng2rng (
 	id int4range,
 	valid_at daterange,
@@ -497,7 +498,20 @@ CREATE TABLE temporal_fk_rng2rng (
 	CONSTRAINT temporal_fk_rng2rng_fk FOREIGN KEY (parent_id, PERIOD valid_at)
 		REFERENCES temporal_rng
 );
-DROP TABLE temporal_fk_rng2rng;
+ERROR:  foreign key uses PERIOD on the referencing table but not the referenced table
+-- (parent_id) REFERENCES [implicit]
+-- This finds the PK (omitting the WITHOUT OVERLAPS element),
+-- but it's not a b-tree index, so it fails anyway.
+-- Anyway it must fail because the two sides have a different definition of "unique".
+CREATE TABLE temporal_fk_rng2rng (
+	id int4range,
+	valid_at daterange,
+	parent_id int4range,
+	CONSTRAINT temporal_fk_rng2rng_pk PRIMARY KEY (id, valid_at WITHOUT OVERLAPS),
+	CONSTRAINT temporal_fk_rng2rng_fk FOREIGN KEY (parent_id)
+		REFERENCES temporal_rng
+);
+ERROR:  only b-tree indexes are supported for foreign keys
 -- should fail because of duplicate referenced columns:
 CREATE TABLE temporal_fk_rng2rng (
 	id int4range,
@@ -577,23 +591,6 @@ Indexes:
 Foreign-key constraints:
     "temporal_fk2_rng2rng_fk" FOREIGN KEY (parent_id1, parent_id2, PERIOD valid_at) REFERENCES temporal_rng2(id1, id2, PERIOD valid_at)
 
--- with inferred PK on the referenced table, and wrong column type:
-ALTER TABLE temporal_fk_rng2rng
-	DROP CONSTRAINT temporal_fk_rng2rng_fk,
-	ALTER COLUMN valid_at TYPE tsrange USING tsrange(lower(valid_at), upper(valid_at));
-ALTER TABLE temporal_fk_rng2rng
-	ADD CONSTRAINT temporal_fk_rng2rng_fk
-	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
-ERROR:  foreign key constraint "temporal_fk_rng2rng_fk" cannot be implemented
-DETAIL:  Key columns "valid_at" and "valid_at" are of incompatible types: tsrange and daterange.
-ALTER TABLE temporal_fk_rng2rng
-	ALTER COLUMN valid_at TYPE daterange USING daterange(lower(valid_at)::date, upper(valid_at)::date);
--- with inferred PK on the referenced table:
-ALTER TABLE temporal_fk_rng2rng
-	ADD CONSTRAINT temporal_fk_rng2rng_fk
-	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
 -- should fail because of duplicate referenced columns:
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk2
@@ -616,7 +613,7 @@ INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[1,2)', dater
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
+	REFERENCES temporal_rng (id, PERIOD valid_at);
 ALTER TABLE temporal_fk_rng2rng
 	DROP CONSTRAINT temporal_fk_rng2rng_fk;
 INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[2,3)', daterange('2018-01-02', '2018-04-01'), '[1,2)');
@@ -624,7 +621,7 @@ INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[2,3)', dater
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
+	REFERENCES temporal_rng (id, PERIOD valid_at);
 ERROR:  insert or update on table "temporal_fk_rng2rng" violates foreign key constraint "temporal_fk_rng2rng_fk"
 DETAIL:  Key (parent_id, valid_at)=([1,2), [2018-01-02,2018-04-01)) is not present in table "temporal_rng".
 -- okay again:
@@ -632,7 +629,7 @@ DELETE FROM temporal_fk_rng2rng;
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
+	REFERENCES temporal_rng (id, PERIOD valid_at);
 --
 -- test pg_get_constraintdef
 --
@@ -716,7 +713,7 @@ ALTER TABLE temporal_fk_rng2rng
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng
+	REFERENCES temporal_rng (id, PERIOD valid_at)
 	ON UPDATE RESTRICT;
 -- a PK update that succeeds because the numeric id isn't referenced:
 INSERT INTO temporal_rng (id, valid_at) VALUES ('[5,6)', daterange('2018-01-01', '2018-02-01'));
@@ -752,7 +749,7 @@ ALTER TABLE temporal_fk_rng2rng
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
+	REFERENCES temporal_rng (id, PERIOD valid_at);
 -- a PK delete that succeeds because the numeric id isn't referenced:
 INSERT INTO temporal_rng (id, valid_at) VALUES ('[5,6)', daterange('2018-01-01', '2018-02-01'));
 DELETE FROM temporal_rng WHERE id = '[5,6)';
@@ -778,7 +775,7 @@ ALTER TABLE temporal_fk_rng2rng
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng
+	REFERENCES temporal_rng (id, PERIOD valid_at)
 	ON DELETE RESTRICT;
 INSERT INTO temporal_rng (id, valid_at) VALUES ('[5,6)', daterange('2018-01-01', '2018-02-01'));
 DELETE FROM temporal_rng WHERE id = '[5,6)';
@@ -805,7 +802,7 @@ ALTER TABLE temporal_fk_rng2rng
 	DROP CONSTRAINT temporal_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_rng
+		REFERENCES temporal_rng (id, PERIOD valid_at)
 		ON DELETE CASCADE ON UPDATE CASCADE;
 ERROR:  invalid ON DELETE action for foreign key constraint using PERIOD
 -- test FK referenced updates SET NULL
@@ -815,7 +812,7 @@ ALTER TABLE temporal_fk_rng2rng
 	DROP CONSTRAINT temporal_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_rng
+		REFERENCES temporal_rng (id, PERIOD valid_at)
 		ON DELETE SET NULL ON UPDATE SET NULL;
 ERROR:  invalid ON DELETE action for foreign key constraint using PERIOD
 -- test FK referenced updates SET DEFAULT
@@ -827,7 +824,7 @@ ALTER TABLE temporal_fk_rng2rng
 	DROP CONSTRAINT temporal_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_rng
+		REFERENCES temporal_rng (id, PERIOD valid_at)
 		ON DELETE SET DEFAULT ON UPDATE SET DEFAULT;
 ERROR:  invalid ON DELETE action for foreign key constraint using PERIOD
 --
@@ -919,7 +916,7 @@ ALTER TABLE temporal_partitioned_fk_rng2rng
 ALTER TABLE temporal_partitioned_fk_rng2rng
 	ADD CONSTRAINT temporal_partitioned_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_partitioned_rng
+	REFERENCES temporal_partitioned_rng (id, PERIOD valid_at)
 	ON DELETE RESTRICT;
 INSERT INTO temporal_partitioned_rng (id, valid_at) VALUES ('[5,6)', daterange('2016-01-01', '2016-02-01'));
 UPDATE temporal_partitioned_rng SET valid_at = daterange('2018-01-01', '2018-02-01') WHERE id = '[5,6)';
@@ -951,7 +948,7 @@ ALTER TABLE temporal_partitioned_fk_rng2rng
 	DROP CONSTRAINT temporal_partitioned_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_partitioned_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_partitioned_rng
+		REFERENCES temporal_partitioned_rng (id, PERIOD valid_at)
 		ON DELETE CASCADE ON UPDATE CASCADE;
 ERROR:  invalid ON DELETE action for foreign key constraint using PERIOD
 --
@@ -964,7 +961,7 @@ ALTER TABLE temporal_partitioned_fk_rng2rng
 	DROP CONSTRAINT temporal_partitioned_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_partitioned_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_partitioned_rng
+		REFERENCES temporal_partitioned_rng (id, PERIOD valid_at)
 		ON DELETE SET NULL ON UPDATE SET NULL;
 ERROR:  invalid ON DELETE action for foreign key constraint using PERIOD
 --
@@ -978,7 +975,7 @@ ALTER TABLE temporal_partitioned_fk_rng2rng
 	DROP CONSTRAINT temporal_partitioned_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_partitioned_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_partitioned_rng
+		REFERENCES temporal_partitioned_rng (id, PERIOD valid_at)
 		ON DELETE SET DEFAULT ON UPDATE SET DEFAULT;
 ERROR:  invalid ON DELETE action for foreign key constraint using PERIOD
 --
diff --git a/src/test/regress/sql/without_overlaps.sql b/src/test/regress/sql/without_overlaps.sql
index b622629f885..48bcaa18a09 100644
--- a/src/test/regress/sql/without_overlaps.sql
+++ b/src/test/regress/sql/without_overlaps.sql
@@ -387,8 +387,8 @@ CREATE TABLE temporal_fk_rng2rng (
 	CONSTRAINT temporal_fk_rng2rng_fk FOREIGN KEY (parent_id)
 		REFERENCES temporal_rng (id, PERIOD valid_at)
 );
-
 -- with inferred PK on the referenced table:
+-- (This is not permitted by the SQL standard. See 11.8 syntax rule 4b.)
 CREATE TABLE temporal_fk_rng2rng (
 	id int4range,
 	valid_at daterange,
@@ -397,7 +397,18 @@ CREATE TABLE temporal_fk_rng2rng (
 	CONSTRAINT temporal_fk_rng2rng_fk FOREIGN KEY (parent_id, PERIOD valid_at)
 		REFERENCES temporal_rng
 );
-DROP TABLE temporal_fk_rng2rng;
+-- (parent_id) REFERENCES [implicit]
+-- This finds the PK (omitting the WITHOUT OVERLAPS element),
+-- but it's not a b-tree index, so it fails anyway.
+-- Anyway it must fail because the two sides have a different definition of "unique".
+CREATE TABLE temporal_fk_rng2rng (
+	id int4range,
+	valid_at daterange,
+	parent_id int4range,
+	CONSTRAINT temporal_fk_rng2rng_pk PRIMARY KEY (id, valid_at WITHOUT OVERLAPS),
+	CONSTRAINT temporal_fk_rng2rng_fk FOREIGN KEY (parent_id)
+		REFERENCES temporal_rng
+);
 
 -- should fail because of duplicate referenced columns:
 CREATE TABLE temporal_fk_rng2rng (
@@ -458,23 +469,6 @@ ALTER TABLE temporal_fk2_rng2rng
 	REFERENCES temporal_rng2 (id1, id2, PERIOD valid_at);
 \d temporal_fk2_rng2rng
 
--- with inferred PK on the referenced table, and wrong column type:
-ALTER TABLE temporal_fk_rng2rng
-	DROP CONSTRAINT temporal_fk_rng2rng_fk,
-	ALTER COLUMN valid_at TYPE tsrange USING tsrange(lower(valid_at), upper(valid_at));
-ALTER TABLE temporal_fk_rng2rng
-	ADD CONSTRAINT temporal_fk_rng2rng_fk
-	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
-ALTER TABLE temporal_fk_rng2rng
-	ALTER COLUMN valid_at TYPE daterange USING daterange(lower(valid_at)::date, upper(valid_at)::date);
-
--- with inferred PK on the referenced table:
-ALTER TABLE temporal_fk_rng2rng
-	ADD CONSTRAINT temporal_fk_rng2rng_fk
-	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
-
 -- should fail because of duplicate referenced columns:
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk2
@@ -499,7 +493,7 @@ INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[1,2)', dater
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
+	REFERENCES temporal_rng (id, PERIOD valid_at);
 ALTER TABLE temporal_fk_rng2rng
 	DROP CONSTRAINT temporal_fk_rng2rng_fk;
 INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[2,3)', daterange('2018-01-02', '2018-04-01'), '[1,2)');
@@ -507,13 +501,13 @@ INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[2,3)', dater
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
+	REFERENCES temporal_rng (id, PERIOD valid_at);
 -- okay again:
 DELETE FROM temporal_fk_rng2rng;
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
+	REFERENCES temporal_rng (id, PERIOD valid_at);
 
 --
 -- test pg_get_constraintdef
@@ -593,7 +587,7 @@ ALTER TABLE temporal_fk_rng2rng
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng
+	REFERENCES temporal_rng (id, PERIOD valid_at)
 	ON UPDATE RESTRICT;
 -- a PK update that succeeds because the numeric id isn't referenced:
 INSERT INTO temporal_rng (id, valid_at) VALUES ('[5,6)', daterange('2018-01-01', '2018-02-01'));
@@ -627,7 +621,7 @@ ALTER TABLE temporal_fk_rng2rng
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng;
+	REFERENCES temporal_rng (id, PERIOD valid_at);
 -- a PK delete that succeeds because the numeric id isn't referenced:
 INSERT INTO temporal_rng (id, valid_at) VALUES ('[5,6)', daterange('2018-01-01', '2018-02-01'));
 DELETE FROM temporal_rng WHERE id = '[5,6)';
@@ -653,7 +647,7 @@ ALTER TABLE temporal_fk_rng2rng
 ALTER TABLE temporal_fk_rng2rng
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_rng
+	REFERENCES temporal_rng (id, PERIOD valid_at)
 	ON DELETE RESTRICT;
 INSERT INTO temporal_rng (id, valid_at) VALUES ('[5,6)', daterange('2018-01-01', '2018-02-01'));
 DELETE FROM temporal_rng WHERE id = '[5,6)';
@@ -680,7 +674,7 @@ ALTER TABLE temporal_fk_rng2rng
 	DROP CONSTRAINT temporal_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_rng
+		REFERENCES temporal_rng (id, PERIOD valid_at)
 		ON DELETE CASCADE ON UPDATE CASCADE;
 
 -- test FK referenced updates SET NULL
@@ -690,7 +684,7 @@ ALTER TABLE temporal_fk_rng2rng
 	DROP CONSTRAINT temporal_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_rng
+		REFERENCES temporal_rng (id, PERIOD valid_at)
 		ON DELETE SET NULL ON UPDATE SET NULL;
 
 -- test FK referenced updates SET DEFAULT
@@ -702,7 +696,7 @@ ALTER TABLE temporal_fk_rng2rng
 	DROP CONSTRAINT temporal_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_rng
+		REFERENCES temporal_rng (id, PERIOD valid_at)
 		ON DELETE SET DEFAULT ON UPDATE SET DEFAULT;
 
 --
@@ -796,7 +790,7 @@ ALTER TABLE temporal_partitioned_fk_rng2rng
 ALTER TABLE temporal_partitioned_fk_rng2rng
 	ADD CONSTRAINT temporal_partitioned_fk_rng2rng_fk
 	FOREIGN KEY (parent_id, PERIOD valid_at)
-	REFERENCES temporal_partitioned_rng
+	REFERENCES temporal_partitioned_rng (id, PERIOD valid_at)
 	ON DELETE RESTRICT;
 INSERT INTO temporal_partitioned_rng (id, valid_at) VALUES ('[5,6)', daterange('2016-01-01', '2016-02-01'));
 UPDATE temporal_partitioned_rng SET valid_at = daterange('2018-01-01', '2018-02-01') WHERE id = '[5,6)';
@@ -828,7 +822,7 @@ ALTER TABLE temporal_partitioned_fk_rng2rng
 	DROP CONSTRAINT temporal_partitioned_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_partitioned_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_partitioned_rng
+		REFERENCES temporal_partitioned_rng (id, PERIOD valid_at)
 		ON DELETE CASCADE ON UPDATE CASCADE;
 
 --
@@ -843,7 +837,7 @@ ALTER TABLE temporal_partitioned_fk_rng2rng
 	DROP CONSTRAINT temporal_partitioned_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_partitioned_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_partitioned_rng
+		REFERENCES temporal_partitioned_rng (id, PERIOD valid_at)
 		ON DELETE SET NULL ON UPDATE SET NULL;
 
 --
@@ -859,7 +853,7 @@ ALTER TABLE temporal_partitioned_fk_rng2rng
 	DROP CONSTRAINT temporal_partitioned_fk_rng2rng_fk,
 	ADD CONSTRAINT temporal_partitioned_fk_rng2rng_fk
 		FOREIGN KEY (parent_id, PERIOD valid_at)
-		REFERENCES temporal_partitioned_rng
+		REFERENCES temporal_partitioned_rng (id, PERIOD valid_at)
 		ON DELETE SET DEFAULT ON UPDATE SET DEFAULT;
 
 --
-- 
2.42.0

