GiST: entryvec->vector[] uses 1-based indexing (FirstOffsetNumber), not 0-based. Reading vector[0] hit uninitialized memory, causing SIGSEGV on large catalogs (14k+ satellites). Fixed in gist_tle_union and gist_tle_picksplit. SP-GiST: PostgreSQL requires the indexed column as the LEFT argument of the operator to form a ScanKey (skey.h:23-26). Flipped &? from (observer_window, tle) to (tle, observer_window) so inner_consistent receives scankeys for tree-level pruning. Removed L0 altitude pruning from inner_consistent — SMA bins don't carry eccentricity, so HEO satellites (e.g. CLUSTER II, e=0.88, SMA ~70000 km, perigee ~2000 km) were falsely pruned. L0 now only narrows SMA range for L1 footprint computation. All 15 regression tests pass. Consistency check on 14,376 satellites confirms 0 false negatives, 0 false positives.
79 lines
3.4 KiB
SQL
79 lines
3.4 KiB
SQL
-- pg_orrery 0.6.0 -> 0.7.0 migration
|
|
--
|
|
-- Adds SP-GiST orbital trie index for satellite pass prediction.
|
|
-- 2-level trie: SMA (L0) + inclination (L1) with query-time RAAN filter.
|
|
-- The &? operator answers "might this satellite be visible?"
|
|
|
|
-- ============================================================
|
|
-- observer_window composite type (query parameter bundle)
|
|
-- ============================================================
|
|
|
|
CREATE TYPE observer_window AS (
|
|
obs observer,
|
|
t_start timestamptz,
|
|
t_end timestamptz,
|
|
min_el float8
|
|
);
|
|
|
|
COMMENT ON TYPE observer_window IS
|
|
'Observation query parameters: observer location, time window, and minimum elevation angle (degrees). Used with the &? visibility cone operator.';
|
|
|
|
-- ============================================================
|
|
-- Visibility cone operator function
|
|
-- ============================================================
|
|
|
|
CREATE FUNCTION tle_visibility_possible(tle, observer_window) RETURNS boolean
|
|
AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
|
|
|
|
COMMENT ON FUNCTION tle_visibility_possible(tle, observer_window) IS
|
|
'Could this satellite be visible from the observer during the time window? Combines altitude, inclination, and RAAN checks. Conservative superset — survivors need SGP4 propagation for ground truth.';
|
|
|
|
-- ============================================================
|
|
-- &? operator (visibility cone check)
|
|
-- ============================================================
|
|
-- The indexed column (tle) MUST be the left argument so PostgreSQL
|
|
-- can form a ScanKey and pass it to inner_consistent for pruning.
|
|
|
|
CREATE OPERATOR &? (
|
|
LEFTARG = tle,
|
|
RIGHTARG = observer_window,
|
|
FUNCTION = tle_visibility_possible,
|
|
RESTRICT = contsel,
|
|
JOIN = contjoinsel
|
|
);
|
|
|
|
COMMENT ON OPERATOR &? (tle, observer_window) IS
|
|
'Visibility cone check: could this satellite be visible from the observer during the time window? Index-accelerated via SP-GiST orbital trie.';
|
|
|
|
-- ============================================================
|
|
-- SP-GiST support functions
|
|
-- ============================================================
|
|
|
|
CREATE FUNCTION spgist_tle_config(internal, internal) RETURNS void
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
|
|
CREATE FUNCTION spgist_tle_choose(internal, internal) RETURNS void
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
|
|
CREATE FUNCTION spgist_tle_picksplit(internal, internal) RETURNS void
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
|
|
CREATE FUNCTION spgist_tle_inner_consistent(internal, internal) RETURNS void
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
|
|
CREATE FUNCTION spgist_tle_leaf_consistent(internal, internal) RETURNS void
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
|
|
-- ============================================================
|
|
-- SP-GiST operator class (opt-in, not DEFAULT)
|
|
-- ============================================================
|
|
|
|
CREATE OPERATOR CLASS tle_spgist_ops
|
|
FOR TYPE tle USING spgist AS
|
|
OPERATOR 1 &? (tle, observer_window),
|
|
FUNCTION 1 spgist_tle_config(internal, internal),
|
|
FUNCTION 2 spgist_tle_choose(internal, internal),
|
|
FUNCTION 3 spgist_tle_picksplit(internal, internal),
|
|
FUNCTION 4 spgist_tle_inner_consistent(internal, internal),
|
|
FUNCTION 5 spgist_tle_leaf_consistent(internal, internal);
|