? GNUmakefile ? config.log ? config.status ? contrib/spi/.deps ? src/Makefile.global ? src/backend/postgres ? src/backend/access/common/.deps ? src/backend/access/gist/.deps ? src/backend/access/hash/.deps ? src/backend/access/heap/.deps ? src/backend/access/index/.deps ? src/backend/access/nbtree/.deps ? src/backend/access/rtree/.deps ? src/backend/access/transam/.deps ? src/backend/bootstrap/.deps ? src/backend/catalog/.deps ? src/backend/catalog/postgres.bki ? src/backend/catalog/postgres.description ? src/backend/commands/.deps ? src/backend/commands/.typecmds.c.swp ? src/backend/executor/.deps ? src/backend/lib/.deps ? src/backend/libpq/.deps ? src/backend/main/.deps ? src/backend/nodes/.deps ? src/backend/optimizer/geqo/.deps ? src/backend/optimizer/path/.deps ? src/backend/optimizer/plan/.deps ? src/backend/optimizer/prep/.deps ? src/backend/optimizer/util/.deps ? src/backend/parser/.deps ? src/backend/port/.deps ? src/backend/postmaster/.deps ? src/backend/regex/.deps ? src/backend/rewrite/.deps ? src/backend/storage/buffer/.deps ? src/backend/storage/file/.deps ? src/backend/storage/freespace/.deps ? src/backend/storage/ipc/.deps ? src/backend/storage/large_object/.deps ? src/backend/storage/lmgr/.deps ? src/backend/storage/page/.deps ? src/backend/storage/smgr/.deps ? src/backend/tcop/.deps ? src/backend/utils/.deps ? src/backend/utils/adt/.deps ? src/backend/utils/cache/.deps ? src/backend/utils/error/.deps ? src/backend/utils/fmgr/.deps ? src/backend/utils/hash/.deps ? src/backend/utils/init/.deps ? src/backend/utils/mb/.deps ? src/backend/utils/mb/conversion_procs/conversion_create.sql ? src/backend/utils/mb/conversion_procs/ascii_and_mic/.deps ? src/backend/utils/mb/conversion_procs/ascii_and_mic/libascii_and_mic.so.0 ? src/backend/utils/mb/conversion_procs/cyrillic_and_mic/.deps ? src/backend/utils/mb/conversion_procs/cyrillic_and_mic/libcyrillic_and_mic.so.0 ? src/backend/utils/mb/conversion_procs/euc_cn_and_mic/.deps ? src/backend/utils/mb/conversion_procs/euc_cn_and_mic/libeuc_cn_and_mic.so.0 ? src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/.deps ? src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/libeuc_jp_and_sjis.so.0 ? src/backend/utils/mb/conversion_procs/euc_kr_and_mic/.deps ? src/backend/utils/mb/conversion_procs/euc_kr_and_mic/libeuc_kr_and_mic.so.0 ? src/backend/utils/mb/conversion_procs/euc_tw_and_big5/.deps ? src/backend/utils/mb/conversion_procs/euc_tw_and_big5/libeuc_tw_and_big5.so.0 ? src/backend/utils/mb/conversion_procs/latin2_and_win1250/.deps ? src/backend/utils/mb/conversion_procs/latin2_and_win1250/liblatin2_and_win1250.so.0 ? src/backend/utils/mb/conversion_procs/latin_and_mic/.deps ? src/backend/utils/mb/conversion_procs/latin_and_mic/liblatin_and_mic.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_ascii/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_ascii/libutf8_and_ascii.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_big5/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_big5/libutf8_and_big5.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/libutf8_and_cyrillic.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/libutf8_and_euc_cn.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/libutf8_and_euc_jp.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/libutf8_and_euc_kr.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/libutf8_and_euc_tw.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_gb18030/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_gb18030/libutf8_and_gb18030.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_gbk/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_gbk/libutf8_and_gbk.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_iso8859/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_iso8859/libutf8_and_iso8859.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/libutf8_and_iso8859_1.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_johab/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_johab/libutf8_and_johab.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_sjis/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_sjis/libutf8_and_sjis.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_tcvn/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_tcvn/libutf8_and_tcvn.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_uhc/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_uhc/libutf8_and_uhc.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_win1250/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_win1250/libutf8_and_win1250.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_win1256/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_win1256/libutf8_and_win1256.so.0 ? src/backend/utils/mb/conversion_procs/utf8_and_win874/.deps ? src/backend/utils/mb/conversion_procs/utf8_and_win874/libutf8_and_win874.so.0 ? src/backend/utils/misc/.deps ? src/backend/utils/mmgr/.deps ? src/backend/utils/sort/.deps ? src/backend/utils/time/.deps ? src/bin/initdb/initdb ? src/bin/initlocation/initlocation ? src/bin/ipcclean/ipcclean ? src/bin/pg_config/pg_config ? src/bin/pg_controldata/.deps ? src/bin/pg_controldata/pg_controldata ? src/bin/pg_ctl/pg_ctl ? src/bin/pg_dump/.deps ? src/bin/pg_dump/pg_dump ? src/bin/pg_dump/pg_dumpall ? src/bin/pg_dump/pg_restore ? src/bin/pg_encoding/.deps ? src/bin/pg_encoding/pg_encoding ? src/bin/pg_id/.deps ? src/bin/pg_id/pg_id ? src/bin/pg_resetxlog/.deps ? src/bin/pg_resetxlog/pg_resetxlog ? src/bin/psql/.deps ? src/bin/psql/psql ? src/bin/scripts/createlang ? src/include/pg_config.h ? src/include/stamp-h ? src/interfaces/ecpg/lib/.deps ? src/interfaces/ecpg/lib/libecpg.so.3 ? src/interfaces/ecpg/preproc/.deps ? src/interfaces/ecpg/preproc/ecpg ? src/interfaces/libpq/.deps ? src/interfaces/libpq/libpq.so.2 ? src/pl/plpgsql/src/.deps ? src/pl/plpgsql/src/libplpgsql.so.1 ? src/test/regress/.deps ? src/test/regress/log ? src/test/regress/pg_regress ? src/test/regress/regression.diffs ? src/test/regress/regression.out ? src/test/regress/results ? src/test/regress/tmp_check ? src/test/regress/expected/constraints.out ? src/test/regress/expected/copy.out ? src/test/regress/expected/create_function_1.out ? src/test/regress/expected/create_function_2.out ? src/test/regress/expected/misc.out ? src/test/regress/sql/constraints.sql ? src/test/regress/sql/copy.sql ? src/test/regress/sql/create_function_1.sql ? src/test/regress/sql/create_function_2.sql ? src/test/regress/sql/misc.sql Index: src/backend/commands/typecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/commands/typecmds.c,v retrieving revision 1.23 diff -c -r1.23 typecmds.c *** src/backend/commands/typecmds.c 2002/12/12 20:35:12 1.23 --- src/backend/commands/typecmds.c 2002/12/13 16:51:51 *************** *** 39,44 **** --- 39,45 ---- #include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_constraint.h" + #include "catalog/pg_depend.h" #include "catalog/pg_type.h" #include "commands/defrem.h" #include "commands/tablecmds.h" *************** *** 58,63 **** --- 59,65 ---- #include "utils/builtins.h" #include "utils/fmgroids.h" #include "utils/lsyscache.h" + #include "utils/relcache.h" #include "utils/syscache.h" static Oid findTypeIOFunction(List *procname, Oid typeOid, bool isOutput); *************** *** 1410,1419 **** List * get_rels_with_domain(Oid domainOid) { ! Relation classRel; ! HeapTuple classTup; ! Relation attRel; ! HeapScanDesc classScan; List *rels = NIL; /* --- 1412,1422 ---- List * get_rels_with_domain(Oid domainOid) { ! Relation depRel; ! HeapTuple depTup; ! ScanKeyData key[2]; ! int nkeys = 0; ! SysScanDesc depScan; List *rels = NIL; /* *************** *** 1421,1479 **** * but once all of the tables and the appropriate attributes are * found we can relese the relation lock. */ ! classRel = relation_openr(RelationRelationName, ExclusiveLock); ! attRel = relation_openr(AttributeRelationName, RowExclusiveLock); ! classScan = heap_beginscan(classRel, SnapshotNow, 0, NULL); /* Scan through pg_class for tables */ ! while ((classTup = heap_getnext(classScan, ForwardScanDirection)) != NULL) { relToCheck *rtc = NULL; - int nkeys = 0; HeapTuple attTup; ! HeapScanDesc attScan; ! ScanKeyData attKey[2]; ! Form_pg_class pg_class; /* Get our pg_class struct */ ! pg_class = (Form_pg_class) GETSTRUCT(classTup); ! ! /* Fetch attributes from pg_attribute for the relation of the type domainOid */ ! ScanKeyEntryInitialize(&attKey[nkeys++], 0, Anum_pg_attribute_attrelid, ! F_OIDEQ, ObjectIdGetDatum(HeapTupleGetOid(classTup))); ! ScanKeyEntryInitialize(&attKey[nkeys++], 0, Anum_pg_attribute_atttypid, ! F_OIDEQ, ObjectIdGetDatum(domainOid)); ! /* Setup to scan pg_attribute */ ! attScan = heap_beginscan(attRel, SnapshotNow, nkeys, attKey); /* Scan through pg_attribute for attributes based on the domain */ ! while ((attTup = heap_getnext(attScan, ForwardScanDirection)) != NULL) { ! if (rtc == NULL) { ! /* First one found for this rel */ ! rtc = (relToCheck *)palloc(sizeof(relToCheck)); ! rtc->atts = (int *)palloc(sizeof(int) * pg_class->relnatts); ! rtc->relOid = HeapTupleGetOid(classTup); ! rtc->natts = 0; ! rels = lcons((void *)rtc, rels); } ! /* Now add the attribute */ ! rtc->atts[rtc->natts++] = ((Form_pg_attribute) GETSTRUCT(attTup))->attnum; } ! heap_endscan(attScan); } ! heap_endscan(classScan); /* Release pg_class, hold pg_attribute for further processing */ ! relation_close(classRel, ExclusiveLock); ! relation_close(attRel, NoLock); return rels; } --- 1424,1522 ---- * but once all of the tables and the appropriate attributes are * found we can relese the relation lock. */ ! depRel = relation_openr(DependRelationName, AccessShareLock); ! ScanKeyEntryInitialize(&key[nkeys++], 0x0, ! Anum_pg_depend_refclassid, F_OIDEQ, ! ObjectIdGetDatum(RelOid_pg_type)); ! ScanKeyEntryInitialize(&key[nkeys++], 0x0, ! Anum_pg_depend_refobjid, F_OIDEQ, ! ObjectIdGetDatum(domainOid)); + depScan = systable_beginscan(depRel, DependReferenceIndex, true, + SnapshotNow, nkeys, key); + /* Scan through pg_class for tables */ ! while (HeapTupleIsValid(depTup = systable_getnext(depScan))) { relToCheck *rtc = NULL; HeapTuple attTup; ! List *rel; ! Form_pg_depend pg_depend; ! Form_pg_attribute pg_att; /* Get our pg_class struct */ ! pg_depend = (Form_pg_depend) GETSTRUCT(depTup); ! /* Must be a pg_attribute entry */ ! if (pg_depend->classid != RelOid_pg_class ! || pg_depend->objsubid == InvalidOid) ! continue; ! /* Confirm the dependency within pg_attribute ! * ! * XXX: Should the attribute tests be an assertion instead? ! */ ! attTup = SearchSysCache(ATTNUM, ! ObjectIdGetDatum(pg_depend->objid), ! Int32GetDatum(pg_depend->objsubid), 0, 0); ! if (!HeapTupleIsValid(attTup)) ! elog(ERROR, "Attribute %d missing for relation %u", ! pg_depend->objsubid, pg_depend->objid); ! ! pg_att = (Form_pg_attribute) GETSTRUCT(attTup); ! ! /* Confirm the column has not been dropped, and is of the expected type */ ! if (pg_att->attisdropped || pg_att->atttypid != domainOid) ! continue; /* Scan through pg_attribute for attributes based on the domain */ ! foreach(rel, rels) { ! relToCheck *rt = (relToCheck *) lfirst(rel); ! ! /* If this is our relation, add the new attribute to the array */ ! if (rt->relOid == pg_depend->objid) { ! rtc = rt; ! rtc->atts[rtc->natts++] = pg_depend->objsubid; ! break; } + } + + /* First attribute found for this relation */ + if (rtc == NULL) + { + Relation r; + + /* + * Use the relcache to find the maximum number of attribute + * to expect for this relation + */ + r = RelationIdGetRelation(pg_depend->objid); + + if (!RelationIsValid(r)) + elog(ERROR, "Relation %u does not exist", pg_depend->objid); + + /* Build the relToCheck entry */ + rtc = (relToCheck *)palloc(sizeof(relToCheck)); + rtc->atts = (int *)palloc(sizeof(int) * RelationGetNumberOfAttributes(r)); + rtc->relOid = pg_depend->objid; + rtc->natts = 0; + rels = lcons((void *)rtc, rels); + rtc->atts[rtc->natts++] = pg_depend->objsubid; ! /* Cleanup */ ! RelationClose(r); } ! ReleaseSysCache(attTup); } ! systable_endscan(depScan); /* Release pg_class, hold pg_attribute for further processing */ ! relation_close(depRel, NoLock); return rels; } Index: src/test/regress/expected/domain.out =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/test/regress/expected/domain.out,v retrieving revision 1.17 diff -c -r1.17 domain.out *** src/test/regress/expected/domain.out 2002/12/12 20:35:16 1.17 --- src/test/regress/expected/domain.out 2002/12/13 16:51:52 *************** *** 201,207 **** ); insert into domnotnull default values; alter domain dnotnulltest set not null; -- fails ! ERROR: ALTER DOMAIN: Relation "domnotnull" Attribute "col1" contains NULL values update domnotnull set col1 = 5; alter domain dnotnulltest set not null; -- fails ERROR: ALTER DOMAIN: Relation "domnotnull" Attribute "col2" contains NULL values --- 201,207 ---- ); insert into domnotnull default values; alter domain dnotnulltest set not null; -- fails ! ERROR: ALTER DOMAIN: Relation "domnotnull" Attribute "col2" contains NULL values update domnotnull set col1 = 5; alter domain dnotnulltest set not null; -- fails ERROR: ALTER DOMAIN: Relation "domnotnull" Attribute "col2" contains NULL values