*** pgsql.q2/src/backend/commands/command.c Thu Nov 16 14:30:19 2000 --- pgsql/src/backend/commands/command.c Sat Dec 2 14:17:31 2000 *************** *** 1287,1312 **** { List *attrl; ! /* go through the fkconstraint->pk_attrs list */ ! foreach(attrl, fkconstraint->pk_attrs) ! { ! Ident *attr=lfirst(attrl); ! found = false; ! for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++) { ! int pkattno = indexStruct->indkey[i]; ! if (pkattno>0) { ! char *name = NameStr(rel_attrs[pkattno-1]->attname); ! if (strcmp(name, attr->name)==0) { ! found = true; ! break; } } } - if (!found) - break; } } ReleaseSysCache(indexTuple); --- 1287,1319 ---- { List *attrl; ! /* Make sure this index has the same number of keys -- It obviously ! * won't match otherwise. */ ! for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++); ! if (i!=length(fkconstraint->pk_attrs)) ! found=false; ! else { ! /* go through the fkconstraint->pk_attrs list */ ! foreach(attrl, fkconstraint->pk_attrs) { ! Ident *attr=lfirst(attrl); ! found = false; ! for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++) { ! int pkattno = indexStruct->indkey[i]; ! if (pkattno>0) { ! char *name = NameStr(rel_attrs[pkattno-1]->attname); ! if (strcmp(name, attr->name)==0) ! { ! found = true; ! break; ! } } } + if (!found) + break; } } } ReleaseSysCache(indexTuple); *** pgsql.q2/src/backend/parser/analyze.c Fri Nov 24 12:16:39 2000 --- pgsql/src/backend/parser/analyze.c Sat Dec 2 15:05:57 2000 *************** *** 1202,1219 **** List *pkattrs; Ident *pkattr; if (ind->unique) { ! foreach(pkattrs, fkconstraint->pk_attrs) { found=0; ! pkattr=lfirst(pkattrs); ! foreach(indparms, ind->indexParams) { ! indparm=lfirst(indparms); ! if (strcmp(indparm->name, pkattr->name)==0) { ! found=1; ! break; } } - if (!found) - break; } } if (found) --- 1202,1227 ---- List *pkattrs; Ident *pkattr; if (ind->unique) { ! int count=0; ! foreach(indparms, ind->indexParams) { ! count++; ! } ! if (count!=length(fkconstraint->pk_attrs)) found=0; ! else { ! foreach(pkattrs, fkconstraint->pk_attrs) { ! found=0; ! pkattr=lfirst(pkattrs); ! foreach(indparms, ind->indexParams) { ! indparm=lfirst(indparms); ! if (strcmp(indparm->name, pkattr->name)==0) { ! found=1; ! break; ! } } + if (!found) + break; } } } if (found) *************** *** 2606,2631 **** { List *attrl; ! /* go through the fkconstraint->pk_attrs list */ ! foreach(attrl, fkconstraint->pk_attrs) ! { ! Ident *attr=lfirst(attrl); ! found = false; ! for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++) { ! int pkattno = indexStruct->indkey[i]; ! if (pkattno>0) { ! char *name = NameStr(pkrel_attrs[pkattno - 1]->attname); ! if (strcmp(name, attr->name)==0) { ! found = true; ! break; } } } - if (!found) - break; } } ReleaseSysCache(indexTuple); --- 2614,2644 ---- { List *attrl; ! for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++); ! if (i!=length(fkconstraint->pk_attrs)) ! found=false; ! else { ! /* go through the fkconstraint->pk_attrs list */ ! foreach(attrl, fkconstraint->pk_attrs) { ! Ident *attr=lfirst(attrl); ! found = false; ! for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++) { ! int pkattno = indexStruct->indkey[i]; ! if (pkattno>0) { ! char *name = NameStr(pkrel_attrs[pkattno - 1]->attname); ! if (strcmp(name, attr->name)==0) ! { ! found = true; ! break; ! } } } + if (!found) + break; } } } ReleaseSysCache(indexTuple); *** pgsql.q2/src/test/regress/sql/foreign_key.sql Mon Aug 28 21:20:47 2000 --- pgsql/src/test/regress/sql/foreign_key.sql Sat Dec 2 15:20:07 2000 *************** *** 418,420 **** --- 418,427 ---- DROP TABLE FKTABLE_FAIL1; DROP TABLE FKTABLE_FAIL2; DROP TABLE PKTABLE; + + -- Test for referencing column number smaller than referenced constraint + CREATE TABLE PKTABLE (ptest1 int, ptest2 int, UNIQUE(ptest1, ptest2)); + CREATE TABLE FKTABLE_FAIL1 (ftest1 int REFERENCES pktable(ptest1)); + + DROP TABLE FKTABLE_FAIL1; + DROP TABLE PKTABLE; *** pgsql.q2/src/test/regress/expected/foreign_key.out Sun Oct 22 16:32:45 2000 --- pgsql/src/test/regress/expected/foreign_key.out Sat Dec 2 15:37:09 2000 *************** *** 703,705 **** --- 703,714 ---- DROP TABLE FKTABLE_FAIL2; ERROR: table "fktable_fail2" does not exist DROP TABLE PKTABLE; + -- Test for referencing column number smaller than referenced constraint + CREATE TABLE PKTABLE (ptest1 int, ptest2 int, UNIQUE(ptest1, ptest2)); + NOTICE: CREATE TABLE/UNIQUE will create implicit index 'pktable_ptest1_key' for table 'pktable' + CREATE TABLE FKTABLE_FAIL1 (ftest1 int REFERENCES pktable(ptest1)); + NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) + ERROR: UNIQUE constraint matching given keys for referenced table "pktable" not found + DROP TABLE FKTABLE_FAIL1; + ERROR: table "fktable_fail1" does not exist + DROP TABLE PKTABLE; *** pgsql.q2/src/test/regress/sql/alter_table.sql Mon Aug 28 21:20:47 2000 --- pgsql/src/test/regress/sql/alter_table.sql Sat Dec 2 15:22:09 2000 *************** *** 169,174 **** --- 169,178 ---- CREATE TABLE tmp3 (a int, b int); + CREATE TABLE tmp4 (a int, b int, unique(a,b)); + + CREATE TABLE tmp5 (a int, b int); + -- Insert rows into tmp2 (pktable) INSERT INTO tmp2 values (1); INSERT INTO tmp2 values (2); *************** *** 194,199 **** --- 198,212 ---- -- Try (and succeed) ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full; + + -- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on + -- tmp4 is a,b + + ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full; + + DROP TABLE tmp5; + + DROP TABLE tmp4; DROP TABLE tmp3; *** pgsql.q2/src/test/regress/expected/alter_table.out Mon Aug 28 21:20:45 2000 --- pgsql/src/test/regress/expected/alter_table.out Sat Dec 2 15:37:14 2000 *************** *** 273,278 **** --- 273,281 ---- CREATE TABLE tmp2 (a int primary key); NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'tmp2_pkey' for table 'tmp2' CREATE TABLE tmp3 (a int, b int); + CREATE TABLE tmp4 (a int, b int, unique(a,b)); + NOTICE: CREATE TABLE/UNIQUE will create implicit index 'tmp4_a_key' for table 'tmp4' + CREATE TABLE tmp5 (a int, b int); -- Insert rows into tmp2 (pktable) INSERT INTO tmp2 values (1); INSERT INTO tmp2 values (2); *************** *** 299,304 **** --- 302,314 ---- -- Try (and succeed) ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full; NOTICE: ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s) + -- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on + -- tmp4 is a,b + ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full; + NOTICE: ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s) + ERROR: UNIQUE constraint matching given keys for referenced table "tmp4" not found + DROP TABLE tmp5; + DROP TABLE tmp4; DROP TABLE tmp3; NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "tmp2" NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "tmp2"