summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/catalog/heap.c8
-rw-r--r--src/backend/catalog/pg_depend.c90
-rw-r--r--src/backend/catalog/pg_shdepend.c66
-rw-r--r--src/include/catalog/indexing.h6
4 files changed, 105 insertions, 65 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index c151ad829d..9d2d357233 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -710,12 +710,6 @@ CheckAttributeType(const char *attname,
}
/*
- * Cap the maximum amount of bytes allocated for InsertPgAttributeTuples()
- * slots.
- */
-#define MAX_PGATTRIBUTE_INSERT_BYTES 65535
-
-/*
* InsertPgAttributeTuples
* Construct and insert a set of tuples in pg_attribute.
*
@@ -750,7 +744,7 @@ InsertPgAttributeTuples(Relation pg_attribute_rel,
/* Initialize the number of slots to use */
nslots = Min(tupdesc->natts,
- (MAX_PGATTRIBUTE_INSERT_BYTES / sizeof(FormData_pg_attribute)));
+ (MAX_CATALOG_MULTI_INSERT_BYTES / sizeof(FormData_pg_attribute)));
slot = palloc(sizeof(TupleTableSlot *) * nslots);
for (int i = 0; i < nslots; i++)
slot[i] = MakeSingleTupleTableSlot(td, &TTSOpsHeapTuple);
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index f263ff13e5..454e569fa9 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -59,10 +59,11 @@ recordMultipleDependencies(const ObjectAddress *depender,
{
Relation dependDesc;
CatalogIndexState indstate;
- HeapTuple tup;
- int i;
- bool nulls[Natts_pg_depend];
- Datum values[Natts_pg_depend];
+ TupleTableSlot **slot;
+ int i,
+ max_slots,
+ slot_init_count,
+ slot_stored_count;
if (nreferenced <= 0)
return; /* nothing to do */
@@ -76,11 +77,21 @@ recordMultipleDependencies(const ObjectAddress *depender,
dependDesc = table_open(DependRelationId, RowExclusiveLock);
+ /*
+ * Allocate the slots to use, but delay costly initialization until we
+ * know that they will be used.
+ */
+ max_slots = Min(nreferenced,
+ MAX_CATALOG_MULTI_INSERT_BYTES / sizeof(FormData_pg_depend));
+ slot = palloc(sizeof(TupleTableSlot *) * max_slots);
+
/* Don't open indexes unless we need to make an update */
indstate = NULL;
- memset(nulls, false, sizeof(nulls));
-
+ /* number of slots currently storing tuples */
+ slot_stored_count = 0;
+ /* number of slots currently initialized */
+ slot_init_count = 0;
for (i = 0; i < nreferenced; i++, referenced++)
{
/*
@@ -88,38 +99,69 @@ recordMultipleDependencies(const ObjectAddress *depender,
* need to record dependencies on it. This saves lots of space in
* pg_depend, so it's worth the time taken to check.
*/
- if (!isObjectPinned(referenced, dependDesc))
- {
- /*
- * Record the Dependency. Note we don't bother to check for
- * duplicate dependencies; there's no harm in them.
- */
- values[Anum_pg_depend_classid - 1] = ObjectIdGetDatum(depender->classId);
- values[Anum_pg_depend_objid - 1] = ObjectIdGetDatum(depender->objectId);
- values[Anum_pg_depend_objsubid - 1] = Int32GetDatum(depender->objectSubId);
-
- values[Anum_pg_depend_refclassid - 1] = ObjectIdGetDatum(referenced->classId);
- values[Anum_pg_depend_refobjid - 1] = ObjectIdGetDatum(referenced->objectId);
- values[Anum_pg_depend_refobjsubid - 1] = Int32GetDatum(referenced->objectSubId);
+ if (isObjectPinned(referenced, dependDesc))
+ continue;
- values[Anum_pg_depend_deptype - 1] = CharGetDatum((char) behavior);
+ if (slot_init_count < max_slots)
+ {
+ slot[slot_stored_count] = MakeSingleTupleTableSlot(RelationGetDescr(dependDesc),
+ &TTSOpsHeapTuple);
+ slot_init_count++;
+ }
- tup = heap_form_tuple(dependDesc->rd_att, values, nulls);
+ ExecClearTuple(slot[slot_stored_count]);
+ /*
+ * Record the dependency. Note we don't bother to check for duplicate
+ * dependencies; there's no harm in them.
+ */
+ slot[slot_stored_count]->tts_values[Anum_pg_depend_refclassid - 1] = ObjectIdGetDatum(referenced->classId);
+ slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjid - 1] = ObjectIdGetDatum(referenced->objectId);
+ slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjsubid - 1] = Int32GetDatum(referenced->objectSubId);
+ slot[slot_stored_count]->tts_values[Anum_pg_depend_deptype - 1] = CharGetDatum((char) behavior);
+ slot[slot_stored_count]->tts_values[Anum_pg_depend_classid - 1] = ObjectIdGetDatum(depender->classId);
+ slot[slot_stored_count]->tts_values[Anum_pg_depend_objid - 1] = ObjectIdGetDatum(depender->objectId);
+ slot[slot_stored_count]->tts_values[Anum_pg_depend_objsubid - 1] = Int32GetDatum(depender->objectSubId);
+
+ memset(slot[slot_stored_count]->tts_isnull, false,
+ slot[slot_stored_count]->tts_tupleDescriptor->natts * sizeof(bool));
+
+ ExecStoreVirtualTuple(slot[slot_stored_count]);
+ slot_stored_count++;
+
+ /* If slots are full, insert a batch of tuples */
+ if (slot_stored_count == max_slots)
+ {
/* fetch index info only when we know we need it */
if (indstate == NULL)
indstate = CatalogOpenIndexes(dependDesc);
- CatalogTupleInsertWithInfo(dependDesc, tup, indstate);
-
- heap_freetuple(tup);
+ CatalogTuplesMultiInsertWithInfo(dependDesc, slot, slot_stored_count,
+ indstate);
+ slot_stored_count = 0;
}
}
+ /* Insert any tuples left in the buffer */
+ if (slot_stored_count > 0)
+ {
+ /* fetch index info only when we know we need it */
+ if (indstate == NULL)
+ indstate = CatalogOpenIndexes(dependDesc);
+
+ CatalogTuplesMultiInsertWithInfo(dependDesc, slot, slot_stored_count,
+ indstate);
+ }
+
if (indstate != NULL)
CatalogCloseIndexes(indstate);
table_close(dependDesc, RowExclusiveLock);
+
+ /* Drop only the number of slots used */
+ for (i = 0; i < slot_init_count; i++)
+ ExecDropSingleTupleTableSlot(slot[i]);
+ pfree(slot);
}
/*
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index 30b234e90e..3dd7afd343 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -787,12 +787,6 @@ checkSharedDependencies(Oid classId, Oid objectId,
/*
- * Cap the maximum amount of bytes allocated for copyTemplateDependencies()
- * slots.
- */
-#define MAX_PGSHDEPEND_INSERT_BYTES 65535
-
-/*
* copyTemplateDependencies
*
* Routine to create the initial shared dependencies of a new database.
@@ -806,21 +800,20 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
ScanKeyData key[1];
SysScanDesc scan;
HeapTuple tup;
- int slotCount;
CatalogIndexState indstate;
TupleTableSlot **slot;
- int nslots,
- max_slots;
- bool slot_init = true;
+ int max_slots,
+ slot_init_count,
+ slot_stored_count;
sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
sdepDesc = RelationGetDescr(sdepRel);
/*
- * Allocate the slots to use, but delay initialization until we know that
- * they will be used.
+ * Allocate the slots to use, but delay costly initialization until we
+ * know that they will be used.
*/
- max_slots = MAX_PGSHDEPEND_INSERT_BYTES / sizeof(FormData_pg_shdepend);
+ max_slots = MAX_CATALOG_MULTI_INSERT_BYTES / sizeof(FormData_pg_shdepend);
slot = palloc(sizeof(TupleTableSlot *) * max_slots);
indstate = CatalogOpenIndexes(sdepRel);
@@ -834,6 +827,11 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
NULL, 1, key);
+ /* number of slots currently storing tuples */
+ slot_stored_count = 0;
+ /* number of slots currently initialized */
+ slot_init_count = 0;
+
/*
* Copy the entries of the original database, changing the database Id to
* that of the new database. Note that because we are not copying rows
@@ -841,41 +839,42 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
* copy the ownership dependency of the template database itself; this is
* what we want.
*/
- slotCount = 0;
while (HeapTupleIsValid(tup = systable_getnext(scan)))
{
Form_pg_shdepend shdep;
- if (slot_init)
- slot[slotCount] = MakeSingleTupleTableSlot(sdepDesc, &TTSOpsHeapTuple);
+ if (slot_init_count < max_slots)
+ {
+ slot[slot_stored_count] = MakeSingleTupleTableSlot(sdepDesc, &TTSOpsHeapTuple);
+ slot_init_count++;
+ }
- ExecClearTuple(slot[slotCount]);
+ ExecClearTuple(slot[slot_stored_count]);
shdep = (Form_pg_shdepend) GETSTRUCT(tup);
- slot[slotCount]->tts_values[Anum_pg_shdepend_dbid] = ObjectIdGetDatum(newDbId);
- slot[slotCount]->tts_values[Anum_pg_shdepend_classid] = shdep->classid;
- slot[slotCount]->tts_values[Anum_pg_shdepend_objid] = shdep->objid;
- slot[slotCount]->tts_values[Anum_pg_shdepend_objsubid] = shdep->objsubid;
- slot[slotCount]->tts_values[Anum_pg_shdepend_refclassid] = shdep->refclassid;
- slot[slotCount]->tts_values[Anum_pg_shdepend_refobjid] = shdep->refobjid;
- slot[slotCount]->tts_values[Anum_pg_shdepend_deptype] = shdep->deptype;
+ slot[slot_stored_count]->tts_values[Anum_pg_shdepend_dbid] = ObjectIdGetDatum(newDbId);
+ slot[slot_stored_count]->tts_values[Anum_pg_shdepend_classid] = shdep->classid;
+ slot[slot_stored_count]->tts_values[Anum_pg_shdepend_objid] = shdep->objid;
+ slot[slot_stored_count]->tts_values[Anum_pg_shdepend_objsubid] = shdep->objsubid;
+ slot[slot_stored_count]->tts_values[Anum_pg_shdepend_refclassid] = shdep->refclassid;
+ slot[slot_stored_count]->tts_values[Anum_pg_shdepend_refobjid] = shdep->refobjid;
+ slot[slot_stored_count]->tts_values[Anum_pg_shdepend_deptype] = shdep->deptype;
- ExecStoreVirtualTuple(slot[slotCount]);
- slotCount++;
+ ExecStoreVirtualTuple(slot[slot_stored_count]);
+ slot_stored_count++;
/* If slots are full, insert a batch of tuples */
- if (slotCount == max_slots)
+ if (slot_stored_count == max_slots)
{
- CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slotCount, indstate);
- slotCount = 0;
- slot_init = false;
+ CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slot_stored_count, indstate);
+ slot_stored_count = 0;
}
}
/* Insert any tuples left in the buffer */
- if (slotCount > 0)
- CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slotCount, indstate);
+ if (slot_stored_count > 0)
+ CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slot_stored_count, indstate);
systable_endscan(scan);
@@ -883,8 +882,7 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId)
table_close(sdepRel, RowExclusiveLock);
/* Drop only the number of slots used */
- nslots = slot_init ? slotCount : max_slots;
- for (int i = 0; i < nslots; i++)
+ for (int i = 0; i < slot_init_count; i++)
ExecDropSingleTupleTableSlot(slot[i]);
pfree(slot);
}
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index a7e2a9b26b..d86729dc6c 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -30,6 +30,12 @@
typedef struct ResultRelInfo *CatalogIndexState;
/*
+ * Cap the maximum amount of bytes allocated for multi-inserts with system
+ * catalogs, limiting the number of slots used.
+ */
+#define MAX_CATALOG_MULTI_INSERT_BYTES 65535
+
+/*
* indexing.c prototypes
*/
extern CatalogIndexState CatalogOpenIndexes(Relation heapRel);