feat: add pgque-specific schema additions#7
Conversation
Add SQL files for pgque schema objects layered on top of PgQ core: - config.sql: singleton config table for pg_cron job IDs - queue_max_retries.sql: add queue_max_retries column to pgque.queue - roles.sql: pgque_reader/writer/admin roles with granular grants - lifecycle.sql: start/stop/uninstall/version function stubs - notify.sql: LISTEN/NOTIFY ticker integration placeholder - tests/test_pgque_additions.sql: acceptance tests Closes #3 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
REV Code Review Report
BLOCKING ISSUES (1)HIGH
NON-BLOCKING (2)MEDIUM
MEDIUM
POTENTIAL ISSUES (2)LOW
LOW
Summary
Verdict: Changes requested. Must fix the PG14/15 REV-assisted review (AI analysis by postgres-ai/rev) |
- Make role grants idempotent on PG14/15 (wrap in exception handler) - Revoke uninstall() from pgque_admin to prevent accidental schema drop - Remove subtransaction in uninstall(); stop() handles its own errors Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
All three review findings addressed in d83fbb6:
|
REV Re-reviewAll blocking and recommended fixes verified:
Verdict: PASSED. Ready to merge. REV-assisted review (AI analysis by postgres-ai/rev) |
The rule is consistently called out in test files (test_api_receive.sql, test_core_events.sql, test_core_retry.sql, etc.) but invisible in user docs, client READMEs, and SQL function comments. I hit it myself while implementing #134 — three operations in one do$$ block silently returned zero rows on the next receive() because the ticker's snapshot predated the maint_retry_events insert's commit. Documents the three operation chains that require separate transactions: send/insert_event → ticker/force_tick → receive/next_batch maint_retry_events → ticker → receive maint_rotate_tables_step1 → maint_rotate_tables_step2 Notes that client default modes (pgxpool, pg.Pool, psycopg autocommit) satisfy the rule transparently, and flags Pool() / rawPool / client.conn as the footgun for users who reach for explicit transactions. User-facing docs (tutorial, examples, reference, client READMEs) still need the same callout — left as a separate docs-only PR per the audit.
Summary
sql/pgque-additions/with pgque-specific schema objects layered on top of transformed PgQ corepgque.configsingleton table storingticker_job_id,maint_job_id,installed_at(for pg_cron integration)queue_max_retries int4column topgque.queuepgque_reader,pgque_writer,pgque_adminroles with granular function-level grants matching actual PgQ function signaturespgque.start(),pgque.stop(),pgque.uninstall(),pgque.version()stubs (Sprint 2 pg_cron integration); allSECURITY DEFINERwith pinnedsearch_pathDesign notes
vendor/pgq/functions/(e.g.,pgque.insert_event(text, text, text),pgque.next_batch_custom(text, text, interval, int4, interval)) rather than wildcards for reader/writer; admin usesgrant execute on all functionsas catch-allcreate table if not exists,do $$ ... if not exists ...,on conflict do nothing)SECURITY DEFINERfunctions pinsearch_pathTest plan
tests/test_pgque_additions.sqlagainst a database with pgque installed (requires Issue Create build/transform.sh — mechanical transformation pipeline #2 transform + Issue Assemble pgque-install.sql and pgque-uninstall.sql with idempotency #4 install script)singleton = truequeue_max_retriescolumn exists onpgque.queuepg_rolespgque.version()returns'1.0.0-dev'Closes #3
🤖 Generated with Claude Code