Summary
pgque.maint() has a branch that executes VACUUM dynamically when maint_operations() returns vacuum work. PostgreSQL rejects VACUUM inside a PL/pgSQL function.
This is usually hidden when autovacuum is enabled because maint_tables_to_vacuum() returns no rows, but installations where that branch activates will see pgque.maint() fail instead of maintaining.
Source behavior
In pgque.maint():
elsif f.func_name = 'vacuum' then
sql := format('vacuum %I.%I', ...);
execute sql;
Evidence
Disposable DB probe by overriding/simulating maint_tables_to_vacuum() output:
select * from pgque.maint_operations();
-- includes: vacuum | pgque.queue
select pgque.maint();
Observed:
ERROR: VACUUM cannot be executed from a function
CONTEXT: SQL statement "vacuum pgque.queue"
PL/pgSQL function maint() line 20 at EXECUTE
Impact
If PgQue expects pgque.maint() to perform vacuum maintenance for rotated/expired tables, that path cannot work as implemented.
pg_cron job calling select pgque.maint() will fail when vacuum work appears.
Suggested fix options
- Do not run VACUUM inside
pgque.maint().
- Return vacuum commands from an advisory function for external scheduler execution.
- Schedule vacuum commands directly via pg_cron as standalone SQL statements.
- Split maintenance: PL/pgSQL-safe operations in
maint(), vacuum outside function.
Test
Create a deterministic condition where maint_operations() returns a vacuum row, then assert the maintenance strategy does not fail.
Environment
Tested on main at 9b3f89f.
Summary
pgque.maint()has a branch that executesVACUUMdynamically whenmaint_operations()returns vacuum work. PostgreSQL rejectsVACUUMinside a PL/pgSQL function.This is usually hidden when autovacuum is enabled because
maint_tables_to_vacuum()returns no rows, but installations where that branch activates will seepgque.maint()fail instead of maintaining.Source behavior
In
pgque.maint():Evidence
Disposable DB probe by overriding/simulating
maint_tables_to_vacuum()output:Observed:
Impact
If PgQue expects
pgque.maint()to perform vacuum maintenance for rotated/expired tables, that path cannot work as implemented.pg_cronjob callingselect pgque.maint()will fail when vacuum work appears.Suggested fix options
pgque.maint().maint(), vacuum outside function.Test
Create a deterministic condition where
maint_operations()returns a vacuum row, then assert the maintenance strategy does not fail.Environment
Tested on
mainat9b3f89f.