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

Commit e7261c4

Browse files
committed
Adjust setRelhassubclassInRelation() to not perform actual heap_update
when the pg_class.relhassubclass value is already correct. This should avoid most cases of the 'tuple concurrently updated' problem that Robert Creager recently complained about. Also remove a bunch of dead code in StoreCatalogInheritance() --- it was still computing the complete list of direct and indirect inheritance ancestors, though that list has not been needed since we got rid of the pg_ipl catalog.
1 parent 4a2c34d commit e7261c4

File tree

1 file changed

+34
-86
lines changed

1 file changed

+34
-86
lines changed

src/backend/commands/tablecmds.c

Lines changed: 34 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
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
*/
@@ -47,6 +47,7 @@
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,
558559
parent->relname)));
559560

560561
parentOids = lappendo(parentOids, RelationGetRelid(relation));
561-
setRelhassubclassInRelation(RelationGetRelid(relation), true);
562562

563563
parentHasOids |= 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
*/
874873
static void
875874
StoreCatalogInheritance(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
*/
895899
relation = heap_openr(InheritsRelationName, RowExclusiveLock);
896900
desc = RelationGetDescr(relation);
897901

898902
seqNumber = 1;
899903
foreach(entry, supers)
900904
{
901-
Oid entryOid = lfirsto(entry);
905+
Oid parentOid = lfirsto(entry);
902906
Datum datum[Natts_pg_inherits];
903907
char nullarr[Natts_pg_inherits];
904908
ObjectAddress childobject,
905909
parentobject;
906910

907911
datum[0] = ObjectIdGetDatum(relationId); /* inhrel */
908-
datum[1] = ObjectIdGetDatum(entryOid); /* inhparent */
912+
datum[1] = ObjectIdGetDatum(parentOid); /* inhparent */
909913
datum[2] = Int16GetDatum(seqNumber); /* inhseqno */
910914

911915
nullarr[0] = ' ';
@@ -924,93 +928,23 @@ StoreCatalogInheritance(Oid relationId, List *supers)
924928
* Store a dependency too
925929
*/
926930
parentobject.classId = RelOid_pg_class;
927-
parentobject.objectId = entryOid;
931+
parentobject.objectId = parentOid;
928932
parentobject.objectSubId = 0;
929933
childobject.classId = RelOid_pg_class;
930934
childobject.objectId = relationId;
931935
childobject.objectSubId = 0;
932936

933937
recordDependencyOn(&childobject, &parentobject, DEPENDENCY_NORMAL);
934938

939+
/*
940+
* Mark the parent as having subclasses.
941+
*/
942+
setRelhassubclassInRelation(parentOid, true);
943+
935944
seqNumber += 1;
936945
}
937946

938947
heap_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-
goto again;
1012-
}
1013-
}
1014948
}
1015949

1016950
/*
@@ -1044,22 +978,36 @@ setRelhassubclassInRelation(Oid relationId, bool relhassubclass)
1044978
{
1045979
Relation relationRelation;
1046980
HeapTuple 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
*/
1051990
relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
1052991
tuple = SearchSysCacheCopy(RELOID,
1053992
ObjectIdGetDatum(relationId),
1054993
0, 0, 0);
1055994
if (!HeapTupleIsValid(tuple))
1056995
elog(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

10641012
heap_freetuple(tuple);
10651013
heap_close(relationRelation, RowExclusiveLock);

0 commit comments

Comments
 (0)