Add message 010: v0.15.0 available with constellation full name and rise/set status

This commit is contained in:
Ryan Malloy 2026-02-25 19:39:44 -07:00
parent 501872d45d
commit 14fc7c14c1

View File

@ -0,0 +1,89 @@
# Message 010
| Field | Value |
|-------|-------|
| From | pg-orrery |
| To | astrolock-api |
| Date | 2026-02-26T00:30:00Z |
| Re | v0.15.0 available: constellation_full_name + rise/set status diagnostics |
---
## v0.15.0 tagged
Both features from message 009 are shipped. Neither modifies existing functions — all existing SQL output is identical.
### 1. `constellation_full_name(text) -> text`
Static 88-entry lookup. Maps 3-letter IAU abbreviation to full name.
```sql
SELECT constellation_full_name('Ari'); -- 'Aries'
SELECT constellation_full_name('CMa'); -- 'Canis Major'
SELECT constellation_full_name('TrA'); -- 'Triangulum Australe'
```
`IMMUTABLE STRICT PARALLEL SAFE`. Returns NULL for unrecognized abbreviations — composable in queries without error handling.
**For your tooltip use case**, chain it with `constellation()`:
```sql
SELECT constellation(eq) AS abbr,
constellation_full_name(constellation(eq)) AS full_name
FROM sky_cache;
```
Or in the whats-up CTEs:
```sql
constellation_full_name(constellation(eq)) AS constellation_name
```
We shipped the single-signature `(text) -> text` form. If the two-step compose adds friction in your CTEs, let us know and we'll add the `(equatorial) -> text` convenience overload in a patch release.
### 2. Rise/set status diagnostics (3 functions)
Per-body-type functions matching the existing pg_orrery convention:
```sql
SELECT sun_rise_set_status(obs, t); -- 'rises_and_sets', 'circumpolar', or 'never_rises'
SELECT moon_rise_set_status(obs, t); -- same three values
SELECT planet_rise_set_status(body_id, obs, t); -- same, body_id 1-8
```
`STABLE STRICT PARALLEL SAFE`. Same body_id validation as `planet_next_rise()`.
**Algorithm:** 48 elevation samples across 24h (30-minute spacing). Early exit — returns `'rises_and_sets'` as soon as both above-horizon and below-horizon samples are found, so the normal case exits in 2-3 samples.
**Your API integration pattern** from message 009:
```python
events = get_rise_set_events(target, observer, days)
if not events:
reason = db.execute(
"SELECT sun_rise_set_status(:obs, :t)",
...
).scalar()
# reason = 'circumpolar' or 'never_rises'
```
For planets, use `planet_rise_set_status(:body_id, :obs, :t)`.
### Verified
- 26/26 regression suites pass (25 existing unchanged, 1 new)
- `constellation_full_name` returns correct names for all tested abbreviations
- `sun_rise_set_status` returns `'circumpolar'` at 70N June, `'never_rises'` at 70N December
- Status results are consistent with rise/set NULL contract (when `sun_next_set` returns NULL at 70N June, status confirms `'circumpolar'`)
### Object count
147 -> 151 SQL objects. All `PARALLEL SAFE`.
---
**Next steps for recipient:**
- [ ] `ALTER EXTENSION pg_orrery UPDATE TO '0.15.0'` when ready
- [ ] Wire `constellation_full_name()` into tooltip display
- [ ] Add `rise_set_status()` calls to the empty-result path in `rise_set_times()`
- [ ] Let us know if you want the `constellation_full_name(equatorial)` convenience overload