Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d7a2b5b

Browse files
committed
Clarify a foreign key error message
Clarify the message about type mismatch in foreign key definition to indicate which column the referencing and which is the referenced one. Reported-by: Jian He <jian.universality@gmail.com> Discussion: https://www.postgresql.org/message-id/CACJufxEL82ao-aXOa=d_-Xip0bix-qdSyNc9fcWxOdkEZFko8w@mail.gmail.com
1 parent 987027b commit d7a2b5b

File tree

5 files changed

+39
-39
lines changed

5 files changed

+39
-39
lines changed

src/backend/commands/tablecmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9961,7 +9961,7 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
99619961
(errcode(ERRCODE_DATATYPE_MISMATCH),
99629962
errmsg("foreign key constraint \"%s\" cannot be implemented",
99639963
fkconstraint->conname),
9964-
errdetail("Key columns \"%s\" and \"%s\" "
9964+
errdetail("Key columns \"%s\" of the referencing table and \"%s\" of the referenced table "
99659965
"are of incompatible types: %s and %s.",
99669966
strVal(list_nth(fkconstraint->fk_attrs, i)),
99679967
strVal(list_nth(fkconstraint->pk_attrs, i)),

src/test/regress/expected/alter_table.out

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -659,12 +659,12 @@ CREATE TEMP TABLE FKTABLE (ftest1 inet);
659659
-- This next should fail, because int=inet does not exist
660660
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
661661
ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented
662-
DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: inet and integer.
662+
DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
663663
-- This should also fail for the same reason, but here we
664664
-- give the column name
665665
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1);
666666
ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented
667-
DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: inet and integer.
667+
DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
668668
DROP TABLE FKTABLE;
669669
-- This should succeed, even though they are different types,
670670
-- because int=int8 exists and is a member of the integer opfamily
@@ -682,7 +682,7 @@ DROP TABLE FKTABLE;
682682
CREATE TEMP TABLE FKTABLE (ftest1 numeric);
683683
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
684684
ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented
685-
DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: numeric and integer.
685+
DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: numeric and integer.
686686
DROP TABLE FKTABLE;
687687
DROP TABLE PKTABLE;
688688
-- On the other hand, this should work because int implicitly promotes to
@@ -704,26 +704,26 @@ CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet,
704704
CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp);
705705
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable;
706706
ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
707-
DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer.
707+
DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: cidr and integer.
708708
DROP TABLE FKTABLE;
709709
-- Again, so should this...
710710
CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp);
711711
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2)
712712
references pktable(ptest1, ptest2);
713713
ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
714-
DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer.
714+
DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: cidr and integer.
715715
DROP TABLE FKTABLE;
716716
-- This fails because we mixed up the column ordering
717717
CREATE TEMP TABLE FKTABLE (ftest1 int, ftest2 inet);
718718
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2)
719719
references pktable(ptest2, ptest1);
720720
ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
721-
DETAIL: Key columns "ftest1" and "ptest2" are of incompatible types: integer and inet.
721+
DETAIL: Key columns "ftest1" of the referencing table and "ptest2" of the referenced table are of incompatible types: integer and inet.
722722
-- As does this...
723723
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest2, ftest1)
724724
references pktable(ptest1, ptest2);
725725
ERROR: foreign key constraint "fktable_ftest2_ftest1_fkey" cannot be implemented
726-
DETAIL: Key columns "ftest2" and "ptest1" are of incompatible types: inet and integer.
726+
DETAIL: Key columns "ftest2" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
727727
DROP TABLE FKTABLE;
728728
DROP TABLE PKTABLE;
729729
-- Test that ALTER CONSTRAINT updates trigger deferrability properly
@@ -3458,7 +3458,7 @@ COMMENT ON CONSTRAINT comment_test_child_fk ON comment_test_child IS 'FOREIGN KE
34583458
ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE text;
34593459
ALTER TABLE comment_test ALTER COLUMN id SET DATA TYPE int USING id::integer;
34603460
ERROR: foreign key constraint "comment_test_child_fk" cannot be implemented
3461-
DETAIL: Key columns "id" and "id" are of incompatible types: text and integer.
3461+
DETAIL: Key columns "id" of the referencing table and "id" of the referenced table are of incompatible types: text and integer.
34623462
-- Comments should be intact
34633463
SELECT col_description('comment_test_child'::regclass, 1) as comment;
34643464
comment

src/test/regress/expected/enum.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ DETAIL: Key (id)=(red) is still referenced from table "enumtest_child".
581581
CREATE TYPE bogus AS ENUM('good', 'bad', 'ugly');
582582
CREATE TABLE enumtest_bogus_child(parent bogus REFERENCES enumtest_parent);
583583
ERROR: foreign key constraint "enumtest_bogus_child_parent_fkey" cannot be implemented
584-
DETAIL: Key columns "parent" and "id" are of incompatible types: bogus and rainbow.
584+
DETAIL: Key columns "parent" of the referencing table and "id" of the referenced table are of incompatible types: bogus and rainbow.
585585
DROP TYPE bogus;
586586
-- check renaming a value
587587
ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson';

src/test/regress/expected/foreign_key.out

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -822,12 +822,12 @@ INSERT INTO PKTABLE VALUES(42);
822822
-- This next should fail, because int=inet does not exist
823823
CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable);
824824
ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented
825-
DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: inet and integer.
825+
DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
826826
-- This should also fail for the same reason, but here we
827827
-- give the column name
828828
CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable(ptest1));
829829
ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented
830-
DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: inet and integer.
830+
DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
831831
-- This should succeed, even though they are different types,
832832
-- because int=int8 exists and is a member of the integer opfamily
833833
CREATE TABLE FKTABLE (ftest1 int8 REFERENCES pktable);
@@ -846,7 +846,7 @@ DROP TABLE FKTABLE;
846846
-- of the integer opfamily)
847847
CREATE TABLE FKTABLE (ftest1 numeric REFERENCES pktable);
848848
ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented
849-
DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: numeric and integer.
849+
DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: numeric and integer.
850850
DROP TABLE PKTABLE;
851851
-- On the other hand, this should work because int implicitly promotes to
852852
-- numeric, and we allow promotion on the FK side
@@ -869,23 +869,23 @@ CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, PRIMARY KEY(ptest1, ptest2));
869869
-- This should fail, because we just chose really odd types
870870
CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable);
871871
ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
872-
DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer.
872+
DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: cidr and integer.
873873
-- Again, so should this...
874874
CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2));
875875
ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
876-
DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer.
876+
DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: cidr and integer.
877877
-- This fails because we mixed up the column ordering
878878
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable);
879879
ERROR: foreign key constraint "fktable_ftest2_ftest1_fkey" cannot be implemented
880-
DETAIL: Key columns "ftest2" and "ptest1" are of incompatible types: inet and integer.
880+
DETAIL: Key columns "ftest2" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
881881
-- As does this...
882882
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest1, ptest2));
883883
ERROR: foreign key constraint "fktable_ftest2_ftest1_fkey" cannot be implemented
884-
DETAIL: Key columns "ftest2" and "ptest1" are of incompatible types: inet and integer.
884+
DETAIL: Key columns "ftest2" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
885885
-- And again..
886886
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest2, ptest1));
887887
ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
888-
DETAIL: Key columns "ftest1" and "ptest2" are of incompatible types: integer and inet.
888+
DETAIL: Key columns "ftest1" of the referencing table and "ptest2" of the referenced table are of incompatible types: integer and inet.
889889
-- This works...
890890
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1));
891891
DROP TABLE FKTABLE;
@@ -906,17 +906,17 @@ DROP TABLE PKTABLE;
906906
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
907907
ptest4) REFERENCES pktable(ptest2, ptest1));
908908
ERROR: foreign key constraint "pktable_ptest3_ptest4_fkey" cannot be implemented
909-
DETAIL: Key columns "ptest3" and "ptest2" are of incompatible types: integer and inet.
909+
DETAIL: Key columns "ptest3" of the referencing table and "ptest2" of the referenced table are of incompatible types: integer and inet.
910910
-- Nor should this... (same reason, we have 4,3 referencing 1,2 which mismatches types
911911
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
912912
ptest3) REFERENCES pktable(ptest1, ptest2));
913913
ERROR: foreign key constraint "pktable_ptest4_ptest3_fkey" cannot be implemented
914-
DETAIL: Key columns "ptest4" and "ptest1" are of incompatible types: inet and integer.
914+
DETAIL: Key columns "ptest4" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
915915
-- Not this one either... Same as the last one except we didn't defined the columns being referenced.
916916
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
917917
ptest3) REFERENCES pktable);
918918
ERROR: foreign key constraint "pktable_ptest4_ptest3_fkey" cannot be implemented
919-
DETAIL: Key columns "ptest4" and "ptest1" are of incompatible types: inet and integer.
919+
DETAIL: Key columns "ptest4" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet and integer.
920920
--
921921
-- Now some cases with inheritance
922922
-- Basic 2 table case: 1 column of matching types.
@@ -1009,40 +1009,40 @@ create table pktable(ptest1 inet, primary key(base1, ptest1)) inherits (pktable_
10091009
-- just generally bad types (with and without column references on the referenced table)
10101010
create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable);
10111011
ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
1012-
DETAIL: Key columns "ftest1" and "base1" are of incompatible types: cidr and integer.
1012+
DETAIL: Key columns "ftest1" of the referencing table and "base1" of the referenced table are of incompatible types: cidr and integer.
10131013
create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable(base1, ptest1));
10141014
ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
1015-
DETAIL: Key columns "ftest1" and "base1" are of incompatible types: cidr and integer.
1015+
DETAIL: Key columns "ftest1" of the referencing table and "base1" of the referenced table are of incompatible types: cidr and integer.
10161016
-- let's mix up which columns reference which
10171017
create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable);
10181018
ERROR: foreign key constraint "fktable_ftest2_ftest1_fkey" cannot be implemented
1019-
DETAIL: Key columns "ftest2" and "base1" are of incompatible types: inet and integer.
1019+
DETAIL: Key columns "ftest2" of the referencing table and "base1" of the referenced table are of incompatible types: inet and integer.
10201020
create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable(base1, ptest1));
10211021
ERROR: foreign key constraint "fktable_ftest2_ftest1_fkey" cannot be implemented
1022-
DETAIL: Key columns "ftest2" and "base1" are of incompatible types: inet and integer.
1022+
DETAIL: Key columns "ftest2" of the referencing table and "base1" of the referenced table are of incompatible types: inet and integer.
10231023
create table fktable(ftest1 int, ftest2 inet, foreign key(ftest1, ftest2) references pktable(ptest1, base1));
10241024
ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented
1025-
DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: integer and inet.
1025+
DETAIL: Key columns "ftest1" of the referencing table and "ptest1" of the referenced table are of incompatible types: integer and inet.
10261026
drop table pktable;
10271027
drop table pktable_base;
10281028
-- 2 columns (1 table), mismatched types
10291029
create table pktable_base(base1 int not null, base2 int);
10301030
create table pktable(ptest1 inet, ptest2 inet[], primary key(base1, ptest1), foreign key(base2, ptest2) references
10311031
pktable(base1, ptest1)) inherits (pktable_base);
10321032
ERROR: foreign key constraint "pktable_base2_ptest2_fkey" cannot be implemented
1033-
DETAIL: Key columns "ptest2" and "ptest1" are of incompatible types: inet[] and inet.
1033+
DETAIL: Key columns "ptest2" of the referencing table and "ptest1" of the referenced table are of incompatible types: inet[] and inet.
10341034
create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(base2, ptest2) references
10351035
pktable(ptest1, base1)) inherits (pktable_base);
10361036
ERROR: foreign key constraint "pktable_base2_ptest2_fkey" cannot be implemented
1037-
DETAIL: Key columns "base2" and "ptest1" are of incompatible types: integer and inet.
1037+
DETAIL: Key columns "base2" of the referencing table and "ptest1" of the referenced table are of incompatible types: integer and inet.
10381038
create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references
10391039
pktable(base1, ptest1)) inherits (pktable_base);
10401040
ERROR: foreign key constraint "pktable_ptest2_base2_fkey" cannot be implemented
1041-
DETAIL: Key columns "ptest2" and "base1" are of incompatible types: inet and integer.
1041+
DETAIL: Key columns "ptest2" of the referencing table and "base1" of the referenced table are of incompatible types: inet and integer.
10421042
create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references
10431043
pktable(base1, ptest1)) inherits (pktable_base);
10441044
ERROR: foreign key constraint "pktable_ptest2_base2_fkey" cannot be implemented
1045-
DETAIL: Key columns "ptest2" and "base1" are of incompatible types: inet and integer.
1045+
DETAIL: Key columns "ptest2" of the referencing table and "base1" of the referenced table are of incompatible types: inet and integer.
10461046
drop table pktable;
10471047
ERROR: table "pktable" does not exist
10481048
drop table pktable_base;
@@ -1154,22 +1154,22 @@ CREATE TEMP TABLE fktable (
11541154
ALTER TABLE fktable ADD CONSTRAINT fk_2_3
11551155
FOREIGN KEY (x2) REFERENCES pktable(id3);
11561156
ERROR: foreign key constraint "fk_2_3" cannot be implemented
1157-
DETAIL: Key columns "x2" and "id3" are of incompatible types: character varying and real.
1157+
DETAIL: Key columns "x2" of the referencing table and "id3" of the referenced table are of incompatible types: character varying and real.
11581158
-- nor to int4
11591159
ALTER TABLE fktable ADD CONSTRAINT fk_2_1
11601160
FOREIGN KEY (x2) REFERENCES pktable(id1);
11611161
ERROR: foreign key constraint "fk_2_1" cannot be implemented
1162-
DETAIL: Key columns "x2" and "id1" are of incompatible types: character varying and integer.
1162+
DETAIL: Key columns "x2" of the referencing table and "id1" of the referenced table are of incompatible types: character varying and integer.
11631163
-- real does not promote to int4
11641164
ALTER TABLE fktable ADD CONSTRAINT fk_3_1
11651165
FOREIGN KEY (x3) REFERENCES pktable(id1);
11661166
ERROR: foreign key constraint "fk_3_1" cannot be implemented
1167-
DETAIL: Key columns "x3" and "id1" are of incompatible types: real and integer.
1167+
DETAIL: Key columns "x3" of the referencing table and "id1" of the referenced table are of incompatible types: real and integer.
11681168
-- int4 does not promote to text
11691169
ALTER TABLE fktable ADD CONSTRAINT fk_1_2
11701170
FOREIGN KEY (x1) REFERENCES pktable(id2);
11711171
ERROR: foreign key constraint "fk_1_2" cannot be implemented
1172-
DETAIL: Key columns "x1" and "id2" are of incompatible types: integer and character varying.
1172+
DETAIL: Key columns "x1" of the referencing table and "id2" of the referenced table are of incompatible types: integer and character varying.
11731173
-- should succeed
11741174
-- int4 promotes to real
11751175
ALTER TABLE fktable ADD CONSTRAINT fk_1_3
@@ -1192,11 +1192,11 @@ FOREIGN KEY (x2,x5,x3) REFERENCES pktable(id2,id1,id3);
11921192
ALTER TABLE fktable ADD CONSTRAINT fk_123_231
11931193
FOREIGN KEY (x1,x2,x3) REFERENCES pktable(id2,id3,id1);
11941194
ERROR: foreign key constraint "fk_123_231" cannot be implemented
1195-
DETAIL: Key columns "x1" and "id2" are of incompatible types: integer and character varying.
1195+
DETAIL: Key columns "x1" of the referencing table and "id2" of the referenced table are of incompatible types: integer and character varying.
11961196
ALTER TABLE fktable ADD CONSTRAINT fk_241_132
11971197
FOREIGN KEY (x2,x4,x1) REFERENCES pktable(id1,id3,id2);
11981198
ERROR: foreign key constraint "fk_241_132" cannot be implemented
1199-
DETAIL: Key columns "x2" and "id1" are of incompatible types: character varying and integer.
1199+
DETAIL: Key columns "x2" of the referencing table and "id1" of the referenced table are of incompatible types: character varying and integer.
12001200
DROP TABLE pktable, fktable;
12011201
-- test a tricky case: we can elide firing the FK check trigger during
12021202
-- an UPDATE if the UPDATE did not change the foreign key

0 commit comments

Comments
 (0)