88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.89 2003/10/12 23:19:21 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.90 2003/10/13 20:02:52 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
4747#include "utils/acl.h"
4848#include "utils/builtins.h"
4949#include "utils/fmgroids.h"
50+ #include "utils/inval.h"
5051#include "utils/lsyscache.h"
5152#include "utils/relcache.h"
5253#include "utils/syscache.h"
@@ -558,7 +559,6 @@ MergeAttributes(List *schema, List *supers, bool istemp,
558559parent -> relname )));
559560
560561parentOids = lappendo (parentOids ,RelationGetRelid (relation ));
561- setRelhassubclassInRelation (RelationGetRelid (relation ), true);
562562
563563parentHasOids |=relation -> rd_rel -> relhasoids ;
564564
@@ -869,7 +869,6 @@ change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
869869 *Updates the system catalogs with proper inheritance information.
870870 *
871871 * supers is a list of the OIDs of the new relation's direct ancestors.
872- * NB: it is destructively changed to include indirect ancestors.
873872 */
874873static void
875874StoreCatalogInheritance (Oid relationId ,List * supers )
@@ -890,22 +889,27 @@ StoreCatalogInheritance(Oid relationId, List *supers)
890889
891890/*
892891 * Store INHERITS information in pg_inherits using direct ancestors
893- * only. Also enter dependencies on the direct ancestors.
892+ * only. Also enter dependencies on the direct ancestors, and make sure
893+ * they are marked with relhassubclass = true.
894+ *
895+ * (Once upon a time, both direct and indirect ancestors were found here
896+ * and then entered into pg_ipl. Since that catalog doesn't exist anymore,
897+ * there's no need to look for indirect ancestors.)
894898 */
895899relation = heap_openr (InheritsRelationName ,RowExclusiveLock );
896900desc = RelationGetDescr (relation );
897901
898902seqNumber = 1 ;
899903foreach (entry ,supers )
900904{
901- Oid entryOid = lfirsto (entry );
905+ Oid parentOid = lfirsto (entry );
902906Datum datum [Natts_pg_inherits ];
903907char nullarr [Natts_pg_inherits ];
904908ObjectAddress childobject ,
905909parentobject ;
906910
907911datum [0 ]= ObjectIdGetDatum (relationId );/* inhrel */
908- datum [1 ]= ObjectIdGetDatum (entryOid );/* inhparent */
912+ datum [1 ]= ObjectIdGetDatum (parentOid );/* inhparent */
909913datum [2 ]= Int16GetDatum (seqNumber );/* inhseqno */
910914
911915nullarr [0 ]= ' ' ;
@@ -924,93 +928,23 @@ StoreCatalogInheritance(Oid relationId, List *supers)
924928 * Store a dependency too
925929 */
926930parentobject .classId = RelOid_pg_class ;
927- parentobject .objectId = entryOid ;
931+ parentobject .objectId = parentOid ;
928932parentobject .objectSubId = 0 ;
929933childobject .classId = RelOid_pg_class ;
930934childobject .objectId = relationId ;
931935childobject .objectSubId = 0 ;
932936
933937recordDependencyOn (& childobject ,& parentobject ,DEPENDENCY_NORMAL );
934938
939+ /*
940+ * Mark the parent as having subclasses.
941+ */
942+ setRelhassubclassInRelation (parentOid , true);
943+
935944seqNumber += 1 ;
936945}
937946
938947heap_close (relation ,RowExclusiveLock );
939-
940- /* ----------------
941- * Expand supers list to include indirect ancestors as well.
942- *
943- * Algorithm:
944- *0. begin with list of direct superclasses.
945- *1. append after each relationId, its superclasses, recursively.
946- *2. remove all but last of duplicates.
947- * ----------------
948- */
949-
950- /*
951- * 1. append after each relationId, its superclasses, recursively.
952- */
953- foreach (entry ,supers )
954- {
955- Oid id = lfirsto (entry );
956- HeapTuple tuple ;
957- int16 number ;
958- List * current ;
959- List * next ;
960-
961- current = entry ;
962- next = lnext (entry );
963-
964- for (number = 1 ;;number += 1 )
965- {
966- tuple = SearchSysCache (INHRELID ,
967- ObjectIdGetDatum (id ),
968- Int16GetDatum (number ),
969- 0 ,0 );
970- if (!HeapTupleIsValid (tuple ))
971- break ;
972-
973- lnext (current )= lconso (((Form_pg_inherits )
974- GETSTRUCT (tuple ))-> inhparent ,
975- NIL );
976- current = lnext (current );
977-
978- ReleaseSysCache (tuple );
979- }
980- lnext (current )= next ;
981- }
982-
983- /*
984- * 2. remove all but last of duplicates.
985- */
986- foreach (entry ,supers )
987- {
988- Oid thisone ;
989- bool found ;
990- List * rest ;
991-
992- again :
993- found = false;
994- thisone = lfirsto (entry );
995- foreach (rest ,lnext (entry ))
996- {
997- if (thisone == lfirsto (rest ))
998- {
999- found = true;
1000- break ;
1001- }
1002- }
1003- if (found )
1004- {
1005- /*
1006- * found a later duplicate, so remove this entry.
1007- */
1008- lfirsto (entry )= lfirsto (lnext (entry ));
1009- lnext (entry )= lnext (lnext (entry ));
1010-
1011- gotoagain ;
1012- }
1013- }
1014948}
1015949
1016950/*
@@ -1044,22 +978,36 @@ setRelhassubclassInRelation(Oid relationId, bool relhassubclass)
1044978{
1045979Relation relationRelation ;
1046980HeapTuple tuple ;
981+ Form_pg_class classtuple ;
1047982
1048983/*
1049984 * Fetch a modifiable copy of the tuple, modify it, update pg_class.
985+ *
986+ * If the tuple already has the right relhassubclass setting, we
987+ * don't need to update it, but we still need to issue an SI inval
988+ * message.
1050989 */
1051990relationRelation = heap_openr (RelationRelationName ,RowExclusiveLock );
1052991tuple = SearchSysCacheCopy (RELOID ,
1053992ObjectIdGetDatum (relationId ),
10549930 ,0 ,0 );
1055994if (!HeapTupleIsValid (tuple ))
1056995elog (ERROR ,"cache lookup failed for relation %u" ,relationId );
996+ classtuple = (Form_pg_class )GETSTRUCT (tuple );
1057997
1058- ((Form_pg_class )GETSTRUCT (tuple ))-> relhassubclass = relhassubclass ;
1059- simple_heap_update (relationRelation ,& tuple -> t_self ,tuple );
998+ if (classtuple -> relhassubclass != relhassubclass )
999+ {
1000+ classtuple -> relhassubclass = relhassubclass ;
1001+ simple_heap_update (relationRelation ,& tuple -> t_self ,tuple );
10601002
1061- /* keep the catalog indexes up to date */
1062- CatalogUpdateIndexes (relationRelation ,tuple );
1003+ /* keep the catalog indexes up to date */
1004+ CatalogUpdateIndexes (relationRelation ,tuple );
1005+ }
1006+ else
1007+ {
1008+ /* no need to change tuple, but force relcache rebuild anyway */
1009+ CacheInvalidateRelcache (relationId );
1010+ }
10631011
10641012heap_freetuple (tuple );
10651013heap_close (relationRelation ,RowExclusiveLock );