@@ -1004,8 +1004,24 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
10041004 ScanKeyData skey ;
10051005 SysScanDesc scan ;
10061006 HeapTuple maptup ;
1007+ TupleDesc mapDesc ;
1008+ TupleTableSlot * * slot ;
1009+ CatalogIndexState indstate ;
1010+ int max_slots ,
1011+ slot_init_count ,
1012+ slot_stored_count ;
10071013
10081014 mapRel = table_open (TSConfigMapRelationId , RowExclusiveLock );
1015+ mapDesc = RelationGetDescr (mapRel );
1016+
1017+ indstate = CatalogOpenIndexes (mapRel );
1018+
1019+ /*
1020+ * Allocate the slots to use, but delay costly initialization until we
1021+ * know that they will be used.
1022+ */
1023+ max_slots = MAX_CATALOG_MULTI_INSERT_BYTES / sizeof (FormData_pg_ts_config_map );
1024+ slot = palloc (sizeof (TupleTableSlot * ) * max_slots );
10091025
10101026 ScanKeyInit (& skey ,
10111027 Anum_pg_ts_config_map_mapcfg ,
@@ -1015,29 +1031,54 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
10151031 scan = systable_beginscan (mapRel , TSConfigMapIndexId , true,
10161032 NULL , 1 , & skey );
10171033
1034+ /* number of slots currently storing tuples */
1035+ slot_stored_count = 0 ;
1036+ /* number of slots currently initialized */
1037+ slot_init_count = 0 ;
1038+
10181039 while (HeapTupleIsValid ((maptup = systable_getnext (scan ))))
10191040 {
10201041 Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map ) GETSTRUCT (maptup );
1021- HeapTuple newmaptup ;
1022- Datum mapvalues [Natts_pg_ts_config_map ];
1023- bool mapnulls [Natts_pg_ts_config_map ];
10241042
1025- memset (mapvalues , 0 , sizeof (mapvalues ));
1026- memset (mapnulls , false, sizeof (mapnulls ));
1043+ if (slot_init_count < max_slots )
1044+ {
1045+ slot [slot_stored_count ] = MakeSingleTupleTableSlot (mapDesc ,
1046+ & TTSOpsHeapTuple );
1047+ slot_init_count ++ ;
1048+ }
1049+
1050+ ExecClearTuple (slot [slot_stored_count ]);
10271051
1028- mapvalues [Anum_pg_ts_config_map_mapcfg - 1 ] = cfgOid ;
1029- mapvalues [Anum_pg_ts_config_map_maptokentype - 1 ] = cfgmap -> maptokentype ;
1030- mapvalues [Anum_pg_ts_config_map_mapseqno - 1 ] = cfgmap -> mapseqno ;
1031- mapvalues [Anum_pg_ts_config_map_mapdict - 1 ] = cfgmap -> mapdict ;
1052+ memset (slot [slot_stored_count ]-> tts_isnull , false,
1053+ slot [slot_stored_count ]-> tts_tupleDescriptor -> natts * sizeof (bool ));
10321054
1033- newmaptup = heap_form_tuple (mapRel -> rd_att , mapvalues , mapnulls );
1055+ slot [slot_stored_count ]-> tts_values [Anum_pg_ts_config_map_mapcfg - 1 ] = cfgOid ;
1056+ slot [slot_stored_count ]-> tts_values [Anum_pg_ts_config_map_maptokentype - 1 ] = cfgmap -> maptokentype ;
1057+ slot [slot_stored_count ]-> tts_values [Anum_pg_ts_config_map_mapseqno - 1 ] = cfgmap -> mapseqno ;
1058+ slot [slot_stored_count ]-> tts_values [Anum_pg_ts_config_map_mapdict - 1 ] = cfgmap -> mapdict ;
10341059
1035- CatalogTupleInsert (mapRel , newmaptup );
1060+ ExecStoreVirtualTuple (slot [slot_stored_count ]);
1061+ slot_stored_count ++ ;
10361062
1037- heap_freetuple (newmaptup );
1063+ /* If slots are full, insert a batch of tuples */
1064+ if (slot_stored_count == max_slots )
1065+ {
1066+ CatalogTuplesMultiInsertWithInfo (mapRel , slot , slot_stored_count ,
1067+ indstate );
1068+ slot_stored_count = 0 ;
1069+ }
10381070 }
10391071
1072+ /* Insert any tuples left in the buffer */
1073+ if (slot_stored_count > 0 )
1074+ CatalogTuplesMultiInsertWithInfo (mapRel , slot , slot_stored_count ,
1075+ indstate );
1076+
1077+ for (int i = 0 ; i < slot_init_count ; i ++ )
1078+ ExecDropSingleTupleTableSlot (slot [i ]);
1079+
10401080 systable_endscan (scan );
1081+ CatalogCloseIndexes (indstate );
10411082 }
10421083
10431084 address = makeConfigurationDependencies (tup , false, mapRel );
@@ -1225,6 +1266,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
12251266 Oid * dictIds ;
12261267 int ndict ;
12271268 ListCell * c ;
1269+ CatalogIndexState indstate ;
12281270
12291271 tsform = (Form_pg_ts_config ) GETSTRUCT (tup );
12301272 cfgId = tsform -> oid ;
@@ -1275,6 +1317,8 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
12751317 i ++ ;
12761318 }
12771319
1320+ indstate = CatalogOpenIndexes (relMap );
1321+
12781322 if (stmt -> replace )
12791323 {
12801324 /*
@@ -1334,38 +1378,68 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
13341378 newtup = heap_modify_tuple (maptup ,
13351379 RelationGetDescr (relMap ),
13361380 repl_val , repl_null , repl_repl );
1337- CatalogTupleUpdate (relMap , & newtup -> t_self , newtup );
1381+ CatalogTupleUpdateWithInfo (relMap , & newtup -> t_self , newtup , indstate );
13381382 }
13391383 }
13401384
13411385 systable_endscan (scan );
13421386 }
13431387 else
13441388 {
1389+ TupleTableSlot * * slot ;
1390+ int slotCount = 0 ;
1391+ int nslots ;
1392+
1393+ /* Allocate the slots to use and initialize them */
1394+ nslots = Min (ntoken * ndict ,
1395+ MAX_CATALOG_MULTI_INSERT_BYTES / sizeof (FormData_pg_ts_config_map ));
1396+ slot = palloc (sizeof (TupleTableSlot * ) * nslots );
1397+ for (i = 0 ; i < nslots ; i ++ )
1398+ slot [i ] = MakeSingleTupleTableSlot (RelationGetDescr (relMap ),
1399+ & TTSOpsHeapTuple );
1400+
13451401 /*
13461402 * Insertion of new entries
13471403 */
13481404 for (i = 0 ; i < ntoken ; i ++ )
13491405 {
13501406 for (j = 0 ; j < ndict ; j ++ )
13511407 {
1352- Datum values [Natts_pg_ts_config_map ];
1353- bool nulls [Natts_pg_ts_config_map ];
1408+ ExecClearTuple (slot [slotCount ]);
1409+
1410+ memset (slot [slotCount ]-> tts_isnull , false,
1411+ slot [slotCount ]-> tts_tupleDescriptor -> natts * sizeof (bool ));
13541412
1355- memset (nulls , false, sizeof (nulls ));
1356- values [Anum_pg_ts_config_map_mapcfg - 1 ] = ObjectIdGetDatum (cfgId );
1357- values [Anum_pg_ts_config_map_maptokentype - 1 ] = Int32GetDatum (tokens [i ]);
1358- values [Anum_pg_ts_config_map_mapseqno - 1 ] = Int32GetDatum (j + 1 );
1359- values [Anum_pg_ts_config_map_mapdict - 1 ] = ObjectIdGetDatum (dictIds [j ]);
1413+ slot [slotCount ]-> tts_values [Anum_pg_ts_config_map_mapcfg - 1 ] = ObjectIdGetDatum (cfgId );
1414+ slot [slotCount ]-> tts_values [Anum_pg_ts_config_map_maptokentype - 1 ] = Int32GetDatum (tokens [i ]);
1415+ slot [slotCount ]-> tts_values [Anum_pg_ts_config_map_mapseqno - 1 ] = Int32GetDatum (j + 1 );
1416+ slot [slotCount ]-> tts_values [Anum_pg_ts_config_map_mapdict - 1 ] = ObjectIdGetDatum (dictIds [j ]);
13601417
1361- tup = heap_form_tuple ( relMap -> rd_att , values , nulls );
1362- CatalogTupleInsert ( relMap , tup ) ;
1418+ ExecStoreVirtualTuple ( slot [ slotCount ] );
1419+ slotCount ++ ;
13631420
1364- heap_freetuple (tup );
1421+ /* If slots are full, insert a batch of tuples */
1422+ if (slotCount == nslots )
1423+ {
1424+ CatalogTuplesMultiInsertWithInfo (relMap , slot , slotCount ,
1425+ indstate );
1426+ slotCount = 0 ;
1427+ }
13651428 }
13661429 }
1430+
1431+ /* Insert any tuples left in the buffer */
1432+ if (slotCount > 0 )
1433+ CatalogTuplesMultiInsertWithInfo (relMap , slot , slotCount ,
1434+ indstate );
1435+
1436+ for (i = 0 ; i < nslots ; i ++ )
1437+ ExecDropSingleTupleTableSlot (slot [i ]);
13671438 }
13681439
1440+ /* clean up */
1441+ CatalogCloseIndexes (indstate );
1442+
13691443 EventTriggerCollectAlterTSConfig (stmt , cfgId , dictIds , ndict );
13701444}
13711445
0 commit comments