@@ -1004,8 +1004,24 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
1004
1004
ScanKeyData skey ;
1005
1005
SysScanDesc scan ;
1006
1006
HeapTuple maptup ;
1007
+ TupleDesc mapDesc ;
1008
+ TupleTableSlot * * slot ;
1009
+ CatalogIndexState indstate ;
1010
+ int max_slots ,
1011
+ slot_init_count ,
1012
+ slot_stored_count ;
1007
1013
1008
1014
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 );
1009
1025
1010
1026
ScanKeyInit (& skey ,
1011
1027
Anum_pg_ts_config_map_mapcfg ,
@@ -1015,29 +1031,54 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
1015
1031
scan = systable_beginscan (mapRel , TSConfigMapIndexId , true,
1016
1032
NULL , 1 , & skey );
1017
1033
1034
+ /* number of slots currently storing tuples */
1035
+ slot_stored_count = 0 ;
1036
+ /* number of slots currently initialized */
1037
+ slot_init_count = 0 ;
1038
+
1018
1039
while (HeapTupleIsValid ((maptup = systable_getnext (scan ))))
1019
1040
{
1020
1041
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 ];
1024
1042
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 ]);
1027
1051
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 ));
1032
1054
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 ;
1034
1059
1035
- CatalogTupleInsert (mapRel , newmaptup );
1060
+ ExecStoreVirtualTuple (slot [slot_stored_count ]);
1061
+ slot_stored_count ++ ;
1036
1062
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
+ }
1038
1070
}
1039
1071
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
+
1040
1080
systable_endscan (scan );
1081
+ CatalogCloseIndexes (indstate );
1041
1082
}
1042
1083
1043
1084
address = makeConfigurationDependencies (tup , false, mapRel );
@@ -1225,6 +1266,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
1225
1266
Oid * dictIds ;
1226
1267
int ndict ;
1227
1268
ListCell * c ;
1269
+ CatalogIndexState indstate ;
1228
1270
1229
1271
tsform = (Form_pg_ts_config ) GETSTRUCT (tup );
1230
1272
cfgId = tsform -> oid ;
@@ -1275,6 +1317,8 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
1275
1317
i ++ ;
1276
1318
}
1277
1319
1320
+ indstate = CatalogOpenIndexes (relMap );
1321
+
1278
1322
if (stmt -> replace )
1279
1323
{
1280
1324
/*
@@ -1334,38 +1378,68 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
1334
1378
newtup = heap_modify_tuple (maptup ,
1335
1379
RelationGetDescr (relMap ),
1336
1380
repl_val , repl_null , repl_repl );
1337
- CatalogTupleUpdate (relMap , & newtup -> t_self , newtup );
1381
+ CatalogTupleUpdateWithInfo (relMap , & newtup -> t_self , newtup , indstate );
1338
1382
}
1339
1383
}
1340
1384
1341
1385
systable_endscan (scan );
1342
1386
}
1343
1387
else
1344
1388
{
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
+
1345
1401
/*
1346
1402
* Insertion of new entries
1347
1403
*/
1348
1404
for (i = 0 ; i < ntoken ; i ++ )
1349
1405
{
1350
1406
for (j = 0 ; j < ndict ; j ++ )
1351
1407
{
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 ));
1354
1412
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 ]);
1360
1417
1361
- tup = heap_form_tuple ( relMap -> rd_att , values , nulls );
1362
- CatalogTupleInsert ( relMap , tup ) ;
1418
+ ExecStoreVirtualTuple ( slot [ slotCount ] );
1419
+ slotCount ++ ;
1363
1420
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
+ }
1365
1428
}
1366
1429
}
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 ]);
1367
1438
}
1368
1439
1440
+ /* clean up */
1441
+ CatalogCloseIndexes (indstate );
1442
+
1369
1443
EventTriggerCollectAlterTSConfig (stmt , cfgId , dictIds , ndict );
1370
1444
}
1371
1445
0 commit comments