Contributing to pg_background
February 9, 2026 · View on GitHub
Thank you for your interest in contributing to pg_background! This document provides guidelines for contributing to the project.
Table of Contents
- Code of Conduct
- Getting Started
- Development Workflow
- Coding Standards
- Testing Requirements
- Commit Guidelines
- Pull Request Process
- Review Process
Code of Conduct
This project follows the PostgreSQL Community Code of Conduct. Please be respectful and constructive in all interactions.
Getting Started
Prerequisites
- PostgreSQL 14 or later (development headers required)
- GCC or Clang compiler
makebuild systemgitfor version control
Setting Up Development Environment
# Clone the repository
git clone https://github.com/vibhorkum/pg_background.git
cd pg_background
# Build the extension
make clean
make
# Install to PostgreSQL (requires appropriate permissions)
sudo make install
# Run regression tests
make installcheck
Development Workflow
- Fork the repository on GitHub
- Create a branch for your feature or bugfix:
git checkout -b feature/my-feature # or git checkout -b bugfix/issue-123 - Make your changes following the coding standards
- Test thoroughly (see Testing Requirements)
- Commit your changes with clear messages
- Push to your fork:
git push origin feature/my-feature - Submit a Pull Request with a clear description
Coding Standards
PostgreSQL Coding Conventions
pg_background follows PostgreSQL coding conventions:
Style Guidelines
- Indentation: 4 spaces (no tabs)
- Line length: Max 80 characters (soft limit; 100 hard limit)
- Braces: K&R style (opening brace on same line)
- Comments: Use C-style
/* */comments, not C++//
Naming Conventions
/* Functions: lowercase with underscores */
static void cleanup_worker_info(dsm_segment *seg, Datum pid_datum);
/* Types: lowercase with underscores */
typedef struct pg_background_worker_info
{
/* ... */
} pg_background_worker_info;
/* Macros: UPPERCASE with underscores */
#define PG_BACKGROUND_MAGIC 0x50674267
/* Constants: UPPERCASE or lowercase depending on context */
#define PGBG_SQL_PREVIEW_LEN 120
Memory Management
- Always use PostgreSQL memory contexts (
palloc,pfree) - Never use C library
malloc/free - Use
TopMemoryContextfor session-lifetime allocations - Clean up resources in error paths using
PG_TRY/PG_CATCH
Error Handling
/* Use ereport for user-facing errors */
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("queue size must be at least %zu bytes", shm_mq_minimum_size)));
/* Use elog for internal assertions */
elog(DEBUG1, "worker_hash entry for PID %d already removed", pid);
Code Formatting
We use pgindent for automatic formatting:
# Format a single file
pgindent pg_background.c
# Check formatting without modifying
pgindent --check pg_background.c
Note: pgindent requires PostgreSQL source tree. See PostgreSQL wiki for setup.
Testing Requirements
Regression Tests
All code changes must include regression tests in sql/pg_background.sql:
-- Test your new feature
SELECT * FROM pg_background_launch_v2('SELECT 1') AS h \gset
SELECT * FROM pg_background_result_v2(:h_pid, :h_cookie) AS (result int);
Update expected output in expected/pg_background.out if needed.
Running Tests
# Run all regression tests
make installcheck
# Run specific test
make installcheck REGRESS=pg_background
# Clean up test artifacts
make installcheckclean
Test Coverage Goals
- Critical paths: 100% coverage (launch, result, detach, cancel)
- Edge cases: PID reuse, DSM cleanup races, error handling
- Error conditions: Invalid inputs, permission failures
- Concurrency: Concurrent detach/result operations
Manual Testing Checklist
Before submitting a PR:
- Tested on PostgreSQL 14 (minimum version)
- Tested on latest stable PostgreSQL version
- No compiler warnings (
-Wall -Wextra) - No memory leaks (use
valgrindif available) - No resource leaks (check
pg_stat_activity,pg_shmem_allocations) - Regression tests pass
- Documentation updated if API changed
Commit Guidelines
Commit Message Format
Short summary (50 chars max)
Detailed explanation of the change, including:
- What was changed and why
- Any behavior changes
- References to issues (e.g., "Fixes #123")
(optional) Breaking changes or migration notes
Good Commit Messages
✅ Good:
Add CHECK_FOR_INTERRUPTS to result loop
Allows cancellation of long-running result retrieval. Without this,
Ctrl-C or pg_terminate_backend() won't interrupt the launcher session
while it's blocked reading results.
Fixes #456
❌ Bad:
Fix bug
Atomic Commits
- One logical change per commit
- Commit compiles and passes tests
- Can be cherry-picked or reverted independently
Pull Request Process
Before Submitting
-
Rebase on latest
main:git fetch origin git rebase origin/main -
Squash fixup commits if needed:
git rebase -i origin/main -
Run full test suite:
make clean && make && make installcheck
PR Description Template
## Description
Brief summary of changes
## Motivation
Why is this change needed?
## Changes Made
- Change 1
- Change 2
## Testing
- [ ] Regression tests added/updated
- [ ] Manual testing performed
- [ ] Tested on PG 14
- [ ] Tested on latest PG
## Breaking Changes
None / List any breaking changes
## Checklist
- [ ] Code follows style guidelines
- [ ] Comments added for complex logic
- [ ] Documentation updated
- [ ] Regression tests pass
- [ ] No compiler warnings
PR Size Guidelines
- Small: < 100 lines changed (preferred)
- Medium: 100-500 lines
- Large: > 500 lines (split if possible)
Large PRs should be split into smaller, logical commits for easier review.
Review Process
What Reviewers Look For
- Correctness: Does it solve the problem?
- Safety: Memory leaks? Race conditions? Resource cleanup?
- Style: Follows PostgreSQL conventions?
- Tests: Adequate test coverage?
- Documentation: Clear comments and README updates?
- Compatibility: Works on PG 14-18?
Responding to Feedback
- Be open to suggestions and constructive criticism
- Respond to all comments, even if just "Fixed" or "Done"
- Push new commits for changes (don't force-push during review)
- Request re-review when ready
Approval Criteria
PRs require:
- ✅ At least one approval from maintainer
- ✅ All CI checks passing
- ✅ No unresolved comments
- ✅ Documentation updated (if applicable)
Development Tips
Debugging
-- Enable debug logging
SET client_min_messages = DEBUG1;
-- Check active workers
SELECT * FROM pg_background_list_v2() AS (...);
-- Check DSM usage
SELECT * FROM pg_shmem_allocations WHERE name LIKE '%pg_background%';
Common Pitfalls
❌ Don't: Call pfree() on BackgroundWorkerHandle
✅ Do: Let PostgreSQL manage handle lifetime
❌ Don't: Use malloc()/free()
✅ Do: Use palloc()/pfree() with proper memory context
❌ Don't: Ignore error context cleanup
✅ Do: Use PG_TRY/PG_CATCH for robust error handling
Useful Resources
- PostgreSQL Backend Internals
- Background Workers Documentation
- Dynamic Shared Memory
- PostgreSQL Extension Best Practices
Questions?
- GitHub Issues: https://github.com/vibhorkum/pg_background/issues
- Discussions: https://github.com/vibhorkum/pg_background/discussions
- Mailing List: pgsql-general@postgresql.org
Thank you for contributing! 🎉