From: Alvaro Herrera Date: Tue, 3 Apr 2018 21:01:22 +0000 (-0300) Subject: Pass correct TupDesc to ri_NullCheck() in Assert X-Git-Tag: REL_11_BETA1~379 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cd5005bc12d0f9a15fe7dddd3e1ac92496608114;p=postgresql Pass correct TupDesc to ri_NullCheck() in Assert Previous coding was passing the wrong table's tuple descriptor, which accidentally fails to fail because no existing test case exercises a foreign key in which the referenced attributes are further to the right of the referencing attributes. Add a test so that further breakage is visible. This got broken in 16828d5c0273. Discussion: https://postgr.es/m/20180403204723.fqte755nukgm42uf@alvherre.pgsql --- diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 3bb708f863..d0fe65cea9 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -514,7 +514,7 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel, bool result; /* Only called for non-null rows */ - Assert(ri_NullCheck(RelationGetDescr(fk_rel), old_row, riinfo, true) == RI_KEYS_NONE_NULL); + Assert(ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true) == RI_KEYS_NONE_NULL); if (SPI_connect() != SPI_OK_CONNECT) elog(ERROR, "SPI_connect failed"); diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out index fef072eddf..e107782466 100644 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@ -1381,6 +1381,19 @@ 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 +-- 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); +insert into pktable2 values (1, 2, 3, 4, 5); +insert into fktable2 values (4, 5); +delete from pktable2; +ERROR: update or delete on table "pktable2" violates foreign key constraint "fktable2_d_fkey" on table "fktable2" +DETAIL: Key (d, e)=(4, 5) is still referenced from table "fktable2". +update pktable2 set d = 5; +ERROR: update or delete on table "pktable2" violates foreign key constraint "fktable2_d_fkey" on table "fktable2" +DETAIL: Key (d, e)=(4, 5) is still referenced from table "fktable2". +drop table pktable2, fktable2; -- -- Test deferred FK check on a tuple deleted by a rolled-back subtransaction -- diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql index 5f19dad03c..63d643c9cc 100644 --- a/src/test/regress/sql/foreign_key.sql +++ b/src/test/regress/sql/foreign_key.sql @@ -1020,6 +1020,16 @@ 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 +-- 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); +insert into pktable2 values (1, 2, 3, 4, 5); +insert into fktable2 values (4, 5); +delete from pktable2; +update pktable2 set d = 5; +drop table pktable2, fktable2; + -- -- Test deferred FK check on a tuple deleted by a rolled-back subtransaction --