@@ -190,7 +190,7 @@ repack_trigger(PG_FUNCTION_ARGS)
190
190
* @param sql_insert SQL to insert into temp table.
191
191
* @param sql_delete SQL to delete from temp table.
192
192
* @param sql_update SQL to update temp table.
193
- * @param sql_pop SQL to delete tuple from log table.
193
+ * @param sql_pop SQL to bulk- delete tuples from log table.
194
194
* @param count Max number of operations, or no count iff <=0.
195
195
* @retval Number of performed operations.
196
196
*/
@@ -203,18 +203,20 @@ repack_apply(PG_FUNCTION_ARGS)
203
203
const char * sql_insert = PG_GETARG_CSTRING (1 );
204
204
const char * sql_delete = PG_GETARG_CSTRING (2 );
205
205
const char * sql_update = PG_GETARG_CSTRING (3 );
206
- const char * sql_pop = PG_GETARG_CSTRING ( 4 );
206
+ /* sql_pop, the fourth arg, will be used in the loop below */
207
207
int32 count = PG_GETARG_INT32 (5 );
208
208
209
209
SPIPlanPtr plan_peek = NULL ;
210
210
SPIPlanPtr plan_insert = NULL ;
211
211
SPIPlanPtr plan_delete = NULL ;
212
212
SPIPlanPtr plan_update = NULL ;
213
- SPIPlanPtr plan_pop = NULL ;
214
213
uint32 n , i ;
215
214
Oid argtypes_peek [1 ] = { INT4OID };
216
215
Datum values_peek [1 ];
217
216
bool nulls_peek [1 ] = { 0 };
217
+ StringInfoData sql_pop ;
218
+
219
+ initStringInfo (& sql_pop );
218
220
219
221
/* authority check */
220
222
must_be_superuser ("repack_apply" );
@@ -252,15 +254,22 @@ repack_apply(PG_FUNCTION_ARGS)
252
254
argtypes [1 ] = SPI_gettypeid (desc , 2 ); /* pk */
253
255
argtypes [2 ] = SPI_gettypeid (desc , 3 ); /* row */
254
256
257
+ resetStringInfo (& sql_pop );
258
+ appendStringInfoString (& sql_pop , PG_GETARG_CSTRING (4 ));
259
+
255
260
for (i = 0 ; i < ntuples ; i ++ , n ++ )
256
261
{
257
262
HeapTuple tuple ;
263
+ char * pkid ;
258
264
259
265
tuple = tuptable -> vals [i ];
260
266
values [0 ] = SPI_getbinval (tuple , desc , 1 , & nulls [0 ]);
261
267
values [1 ] = SPI_getbinval (tuple , desc , 2 , & nulls [1 ]);
262
268
values [2 ] = SPI_getbinval (tuple , desc , 3 , & nulls [2 ]);
263
269
270
+ pkid = SPI_getvalue (tuple , desc , 1 );
271
+ Assert (pkid != NULL );
272
+
264
273
if (nulls [1 ])
265
274
{
266
275
/* INSERT */
@@ -282,15 +291,26 @@ repack_apply(PG_FUNCTION_ARGS)
282
291
plan_update = repack_prepare (sql_update , 2 , & argtypes [1 ]);
283
292
execute_plan (SPI_OK_UPDATE , plan_update , & values [1 ], & nulls [1 ]);
284
293
}
285
- /* Delete tuple in log.
286
- * XXX It would be a lot more efficient to perform
287
- * this DELETE in bulk, but be careful to only
288
- * delete log entries we have actually processed.
294
+
295
+ /* Add the primary key ID of each row from the log
296
+ * table we have processed so far to this
297
+ * DELETE ... IN (...) query string, so we
298
+ * can delete all the rows we have processed at-once.
289
299
*/
290
- if (plan_pop == NULL )
291
- plan_pop = repack_prepare (sql_pop , 1 , argtypes );
292
- execute_plan (SPI_OK_DELETE , plan_pop , values , nulls );
300
+ if (i == 0 )
301
+ appendStringInfoString (& sql_pop , pkid );
302
+ else
303
+ appendStringInfo (& sql_pop , ",%s" , pkid );
304
+ pfree (pkid );
293
305
}
306
+ /* i must be > 0 (and hence we must have some rows to delete)
307
+ * since SPI_processed > 0
308
+ */
309
+ Assert (i > 0 );
310
+ appendStringInfoString (& sql_pop , ");" );
311
+
312
+ /* Bulk delete of processed rows from the log table */
313
+ execute (SPI_OK_DELETE , sql_pop .data );
294
314
295
315
SPI_freetuptable (tuptable );
296
316
}
0 commit comments