*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.112 2000/11/16 22:30:19 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.113 2000/12/05 19:57:55 tgl Exp $
*
* NOTES
* The PerformAddAttribute() code, like most of the relation
{
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++)
+ /* 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)
{
- int pkattno = indexStruct->indkey[i];
- if (pkattno>0)
+ Ident *attr=lfirst(attrl);
+ found = false;
+ for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
{
- char *name = NameStr(rel_attrs[pkattno-1]->attname);
- if (strcmp(name, attr->name)==0)
+ int pkattno = indexStruct->indkey[i];
+ if (pkattno>0)
{
- found = true;
- break;
+ char *name = NameStr(rel_attrs[pkattno-1]->attname);
+ if (strcmp(name, attr->name)==0)
+ {
+ found = true;
+ break;
+ }
}
}
+ if (!found)
+ break;
}
- if (!found)
- break;
}
}
ReleaseSysCache(indexTuple);
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: analyze.c,v 1.169 2000/12/05 19:15:10 tgl Exp $
+ * $Id: analyze.c,v 1.170 2000/12/05 19:57:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
List *pkattrs;
Ident *pkattr;
if (ind->unique) {
- foreach(pkattrs, fkconstraint->pk_attrs) {
+ int count=0;
+ foreach(indparms, ind->indexParams) {
+ count++;
+ }
+ if (count!=length(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;
+ 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)
- break;
}
}
if (found)
{
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++)
+ 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)
{
- int pkattno = indexStruct->indkey[i];
- if (pkattno>0)
+ Ident *attr=lfirst(attrl);
+ found = false;
+ for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
{
- char *name = NameStr(pkrel_attrs[pkattno - 1]->attname);
- if (strcmp(name, attr->name)==0)
+ int pkattno = indexStruct->indkey[i];
+ if (pkattno>0)
{
- found = true;
- break;
+ char *name = NameStr(pkrel_attrs[pkattno - 1]->attname);
+ if (strcmp(name, attr->name)==0)
+ {
+ found = true;
+ break;
+ }
}
}
+ if (!found)
+ break;
}
- if (!found)
- break;
}
}
ReleaseSysCache(indexTuple);
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);
-- 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"
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;
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);
-- 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;
DROP TABLE tmp2;
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;