aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/pg_inherits.c82
-rw-r--r--src/backend/commands/tablecmds.c18
-rw-r--r--src/include/catalog/catversion.h4
-rw-r--r--src/include/catalog/indexing.h5
4 files changed, 82 insertions, 27 deletions
diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c
index 8ae368b7413..4106417fb31 100644
--- a/src/backend/catalog/pg_inherits.c
+++ b/src/backend/catalog/pg_inherits.c
@@ -13,13 +13,15 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_inherits.c,v 1.3 2009/06/11 14:48:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_inherits.c,v 1.4 2009/12/29 22:00:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+#include "access/genam.h"
#include "access/heapam.h"
+#include "catalog/indexing.h"
#include "catalog/pg_class.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_inherits_fn.h"
@@ -29,6 +31,8 @@
#include "utils/syscache.h"
#include "utils/tqual.h"
+static int oid_cmp(const void *p1, const void *p2);
+
/*
* find_inheritance_children
@@ -46,10 +50,14 @@ find_inheritance_children(Oid parentrelId, LOCKMODE lockmode)
{
List *list = NIL;
Relation relation;
- HeapScanDesc scan;
+ SysScanDesc scan;
ScanKeyData key[1];
HeapTuple inheritsTuple;
Oid inhrelid;
+ Oid *oidarr;
+ int maxoids,
+ numoids,
+ i;
/*
* Can skip the scan if pg_class shows the relation has never had a
@@ -59,21 +67,52 @@ find_inheritance_children(Oid parentrelId, LOCKMODE lockmode)
return NIL;
/*
- * XXX might be a good idea to create an index on pg_inherits' inhparent
- * field, so that we can use an indexscan instead of sequential scan here.
- * However, in typical databases pg_inherits won't have enough entries to
- * justify an indexscan...
+ * Scan pg_inherits and build a working array of subclass OIDs.
*/
+ maxoids = 32;
+ oidarr = (Oid *) palloc(maxoids * sizeof(Oid));
+ numoids = 0;
+
relation = heap_open(InheritsRelationId, AccessShareLock);
+
ScanKeyInit(&key[0],
Anum_pg_inherits_inhparent,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(parentrelId));
- scan = heap_beginscan(relation, SnapshotNow, 1, key);
- while ((inheritsTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
+ scan = systable_beginscan(relation, InheritsParentIndexId, true,
+ SnapshotNow, 1, key);
+
+ while ((inheritsTuple = systable_getnext(scan)) != NULL)
{
inhrelid = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhrelid;
+ if (numoids >= maxoids)
+ {
+ maxoids *= 2;
+ oidarr = (Oid *) repalloc(oidarr, maxoids * sizeof(Oid));
+ }
+ oidarr[numoids++] = inhrelid;
+ }
+
+ systable_endscan(scan);
+
+ heap_close(relation, AccessShareLock);
+
+ /*
+ * If we found more than one child, sort them by OID. This ensures
+ * reasonably consistent behavior regardless of the vagaries of an
+ * indexscan. This is important since we need to be sure all backends
+ * lock children in the same order to avoid needless deadlocks.
+ */
+ if (numoids > 1)
+ qsort(oidarr, numoids, sizeof(Oid), oid_cmp);
+
+ /*
+ * Acquire locks and build the result list.
+ */
+ for (i = 0; i < numoids; i++)
+ {
+ inhrelid = oidarr[i];
if (lockmode != NoLock)
{
@@ -99,8 +138,7 @@ find_inheritance_children(Oid parentrelId, LOCKMODE lockmode)
list = lappend_oid(list, inhrelid);
}
- heap_endscan(scan);
- heap_close(relation, AccessShareLock);
+ pfree(oidarr);
return list;
}
@@ -231,7 +269,7 @@ typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId)
{
Oid this_relid = lfirst_oid(queue_item);
ScanKeyData skey;
- HeapScanDesc inhscan;
+ SysScanDesc inhscan;
HeapTuple inhtup;
/*
@@ -255,9 +293,10 @@ typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId)
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(this_relid));
- inhscan = heap_beginscan(inhrel, SnapshotNow, 1, &skey);
+ inhscan = systable_beginscan(inhrel, InheritsRelidSeqnoIndexId, true,
+ SnapshotNow, 1, &skey);
- while ((inhtup = heap_getnext(inhscan, ForwardScanDirection)) != NULL)
+ while ((inhtup = systable_getnext(inhscan)) != NULL)
{
Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inhtup);
Oid inhparent = inh->inhparent;
@@ -273,7 +312,7 @@ typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId)
queue = lappend_oid(queue, inhparent);
}
- heap_endscan(inhscan);
+ systable_endscan(inhscan);
if (result)
break;
@@ -287,3 +326,18 @@ typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId)
return result;
}
+
+
+/* qsort comparison function */
+static int
+oid_cmp(const void *p1, const void *p2)
+{
+ Oid v1 = *((const Oid *) p1);
+ Oid v2 = *((const Oid *) p2);
+
+ if (v1 < v2)
+ return -1;
+ if (v1 > v2)
+ return 1;
+ return 0;
+}
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 55954738088..0412aaf73f2 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.311 2009/12/23 16:43:43 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.312 2009/12/29 22:00:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1793,8 +1793,8 @@ StoreCatalogInheritance1(Oid relationId, Oid parentOid,
int16 seqNumber, Relation inhRelation)
{
TupleDesc desc = RelationGetDescr(inhRelation);
- Datum datum[Natts_pg_inherits];
- bool nullarr[Natts_pg_inherits];
+ Datum values[Natts_pg_inherits];
+ bool nulls[Natts_pg_inherits];
ObjectAddress childobject,
parentobject;
HeapTuple tuple;
@@ -1802,15 +1802,13 @@ StoreCatalogInheritance1(Oid relationId, Oid parentOid,
/*
* Make the pg_inherits entry
*/
- datum[0] = ObjectIdGetDatum(relationId); /* inhrelid */
- datum[1] = ObjectIdGetDatum(parentOid); /* inhparent */
- datum[2] = Int16GetDatum(seqNumber); /* inhseqno */
+ values[Anum_pg_inherits_inhrelid - 1] = ObjectIdGetDatum(relationId);
+ values[Anum_pg_inherits_inhparent - 1] = ObjectIdGetDatum(parentOid);
+ values[Anum_pg_inherits_inhseqno - 1] = Int16GetDatum(seqNumber);
- nullarr[0] = false;
- nullarr[1] = false;
- nullarr[2] = false;
+ memset(nulls, 0, sizeof(nulls));
- tuple = heap_form_tuple(desc, datum, nullarr);
+ tuple = heap_form_tuple(desc, values, nulls);
simple_heap_insert(inhRelation, tuple);
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 0c4ce005295..05ee9590260 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.562 2009/12/29 20:11:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.563 2009/12/29 22:00:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200912281
+#define CATALOG_VERSION_NO 200912291
#endif
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index a5d93ed4455..a7ab8721c7a 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.112 2009/12/29 20:11:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.113 2009/12/29 22:00:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -156,6 +156,9 @@ DECLARE_UNIQUE_INDEX(pg_index_indexrelid_index, 2679, on pg_index using btree(in
DECLARE_UNIQUE_INDEX(pg_inherits_relid_seqno_index, 2680, on pg_inherits using btree(inhrelid oid_ops, inhseqno int4_ops));
#define InheritsRelidSeqnoIndexId 2680
+/* This following index is not used for a cache and is not unique */
+DECLARE_INDEX(pg_inherits_parent_index, 2187, on pg_inherits using btree(inhparent oid_ops));
+#define InheritsParentIndexId 2187
DECLARE_UNIQUE_INDEX(pg_language_name_index, 2681, on pg_language using btree(lanname name_ops));
#define LanguageNameIndexId 2681