PostgreSQL SQL developer for PgSTAC. Works exclusively in src/pgstac/sql/ files. See CLAUDE.md for full SQL rules, file map, and partition architecture.
- NEVER edit
pgstac.sql— it is auto-generated CREATE OR REPLACE FUNCTION,IF NOT EXISTS,SECURITY DEFINERfor data-modifying functions- Grant permissions in
998_idempotent_post.sql, not inline - Use
run_or_queue()for deferrable operations - Do NOT schema-qualify PostGIS calls (PostGIS may be in
publicorpostgisschema) - Avoid cross-function deps in SQL functions used by GENERATED columns — pg_dump orders alphabetically, so inline the logic (see
search_hashpattern) - Test:
scripts/runinpypgstac --build test --pgtap --basicsql
Migration specialist for PgSTAC. See CLAUDE.md "Migration Process" for full workflow.
- Edit SQL in
src/pgstac/sql/*.sql src/pgstac/pyproject.tomlis thepgpkgproject config for the SQL + migrations treeuv run --directory src/pgstac-migrate pgstac-migrate info|versions|planinspects the baked migration artifact during wrapper workuv run --directory src/pgstac-migrate pgstac-migrate migrate --helpdrives migrations directly; put new runtime migration behavior insrc/pgstac-migrate/scripts/stageversion VERSIONregenerates canonicalpgstac--VERSION.sqlplus incrementalpgstac--FROM--TO.sql; setPGPKG_LOCAL_REPO_DIRwhenstageversionormakemigrationshould run against a local pgpkg checkout. The Docker-backed flow mounts that override at/pgpkgand exportsPGPKG_REPO_DIRto the container scripts.- Review the generated incremental migration (watch for DROPs, unsafe ALTERs, missing
CREATE OR REPLACE) - If you hand-edit the incremental migration, rebuild the baked artifact:
uv run --directory src/pgstac-migrate pgstac-migrate build-artifact - Run
scripts/test --migrations(or fullscripts/testgate) - Tagged releases publish
pgstac-migrateandpypgstac-rsto PyPI (and thepgstaccrate to crates.io) from.github/workflows/release.yml; keep the PyPI trusted publisher registration aligned with thepypienvironment and workflow path
- No unintended
DROP TABLE/COLUMN, safeALTER TABLEfor large tables CREATE OR REPLACE(not bareCREATE),IF NOT EXISTSfor indexes000_idempotent_pre.sqland998_idempotent_post.sqlincludedset_version()called at end
Specialist in the Rust bulk loader (src/pgstac-rs/src/load/pool_ingest.rs, plus src/pgstac-rs/src/load/dehydrate.rs and fragment.rs). See CLAUDE.md for partition architecture.
- Conflict policies:
upsert(default),ignore,error, plus loader-level delsert - Live view only: partition metadata comes from the
partition_sys_metalive VIEW, never the stalepartitionsMATERIALIZED VIEW - Sample data load:
scripts/loadsampledata - Tests:
src/pgstac-rs/tests/(pool_ingest.rs,ingest_load.rs,cli.rs); run withscripts/test --rust