EnumValuesCreate(Oid enumTypeOid, List *vals)
{
Relation pg_enum;
- NameData enumlabel;
Oid *oids;
int elemno,
num_elems;
- Datum values[Natts_pg_enum];
- bool nulls[Natts_pg_enum];
ListCell *lc;
- HeapTuple tup;
+ int slotCount = 0;
+ int nslots;
+ CatalogIndexState indstate;
+ TupleTableSlot **slot;
num_elems = list_length(vals);
qsort(oids, num_elems, sizeof(Oid), oid_cmp);
/* and make the entries */
- memset(nulls, false, sizeof(nulls));
+ indstate = CatalogOpenIndexes(pg_enum);
+
+ /* allocate the slots to use and initialize them */
+ nslots = Min(num_elems,
+ MAX_CATALOG_MULTI_INSERT_BYTES / sizeof(FormData_pg_enum));
+ slot = palloc(sizeof(TupleTableSlot *) * nslots);
+ for (int i = 0; i < nslots; i++)
+ slot[i] = MakeSingleTupleTableSlot(RelationGetDescr(pg_enum),
+ &TTSOpsHeapTuple);
elemno = 0;
foreach(lc, vals)
{
char *lab = strVal(lfirst(lc));
+ Name enumlabel = palloc0(NAMEDATALEN);
/*
* labels are stored in a name field, for easier syscache lookup, so
errdetail("Labels must be %d bytes or less.",
NAMEDATALEN - 1)));
- values[Anum_pg_enum_oid - 1] = ObjectIdGetDatum(oids[elemno]);
- values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid);
- values[Anum_pg_enum_enumsortorder - 1] = Float4GetDatum(elemno + 1);
- namestrcpy(&enumlabel, lab);
- values[Anum_pg_enum_enumlabel - 1] = NameGetDatum(&enumlabel);
+ ExecClearTuple(slot[slotCount]);
- tup = heap_form_tuple(RelationGetDescr(pg_enum), values, nulls);
+ memset(slot[slotCount]->tts_isnull, false,
+ slot[slotCount]->tts_tupleDescriptor->natts * sizeof(bool));
- CatalogTupleInsert(pg_enum, tup);
- heap_freetuple(tup);
+ slot[slotCount]->tts_values[Anum_pg_enum_oid - 1] = ObjectIdGetDatum(oids[elemno]);
+ slot[slotCount]->tts_values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid);
+ slot[slotCount]->tts_values[Anum_pg_enum_enumsortorder - 1] = Float4GetDatum(elemno + 1);
+
+ namestrcpy(enumlabel, lab);
+ slot[slotCount]->tts_values[Anum_pg_enum_enumlabel - 1] = NameGetDatum(enumlabel);
+
+ ExecStoreVirtualTuple(slot[slotCount]);
+ slotCount++;
+
+ /* if slots are full, insert a batch of tuples */
+ if (slotCount == nslots)
+ {
+ CatalogTuplesMultiInsertWithInfo(pg_enum, slot, slotCount,
+ indstate);
+ slotCount = 0;
+ }
elemno++;
}
+ /* Insert any tuples left in the buffer */
+ if (slotCount > 0)
+ CatalogTuplesMultiInsertWithInfo(pg_enum, slot, slotCount,
+ indstate);
+
/* clean up */
pfree(oids);
+ for (int i = 0; i < nslots; i++)
+ ExecDropSingleTupleTableSlot(slot[i]);
+ CatalogCloseIndexes(indstate);
table_close(pg_enum, RowExclusiveLock);
}