90 lines
3.0 KiB
Markdown
90 lines
3.0 KiB
Markdown
# 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
|