diff --git a/sql/pg_orrery--0.6.0--0.7.0.sql b/sql/pg_orrery--0.6.0--0.7.0.sql index 0f344a5..f302733 100644 --- a/sql/pg_orrery--0.6.0--0.7.0.sql +++ b/sql/pg_orrery--0.6.0--0.7.0.sql @@ -22,25 +22,27 @@ COMMENT ON TYPE observer_window IS -- Visibility cone operator function -- ============================================================ -CREATE FUNCTION tle_visibility_possible(observer_window, tle) RETURNS boolean +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(observer_window, tle) IS +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 = observer_window, - RIGHTARG = tle, + LEFTARG = tle, + RIGHTARG = observer_window, FUNCTION = tle_visibility_possible, RESTRICT = contsel, JOIN = contjoinsel ); -COMMENT ON OPERATOR &? (observer_window, tle) IS +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.'; -- ============================================================ @@ -68,7 +70,7 @@ CREATE FUNCTION spgist_tle_leaf_consistent(internal, internal) RETURNS void CREATE OPERATOR CLASS tle_spgist_ops FOR TYPE tle USING spgist AS - OPERATOR 1 &? (observer_window, tle), + 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), diff --git a/sql/pg_orrery--0.7.0.sql b/sql/pg_orrery--0.7.0.sql index 77176c5..3b18bbd 100644 --- a/sql/pg_orrery--0.7.0.sql +++ b/sql/pg_orrery--0.7.0.sql @@ -907,25 +907,27 @@ COMMENT ON TYPE observer_window IS -- Visibility cone operator function -- ============================================================ -CREATE FUNCTION tle_visibility_possible(observer_window, tle) RETURNS boolean +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(observer_window, tle) IS +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 = observer_window, - RIGHTARG = tle, + LEFTARG = tle, + RIGHTARG = observer_window, FUNCTION = tle_visibility_possible, RESTRICT = contsel, JOIN = contjoinsel ); -COMMENT ON OPERATOR &? (observer_window, tle) IS +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.'; -- ============================================================ @@ -953,7 +955,7 @@ CREATE FUNCTION spgist_tle_leaf_consistent(internal, internal) RETURNS void CREATE OPERATOR CLASS tle_spgist_ops FOR TYPE tle USING spgist AS - OPERATOR 1 &? (observer_window, tle), + 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), diff --git a/src/gist_tle.c b/src/gist_tle.c index 5e3e12e..445856c 100644 --- a/src/gist_tle.c +++ b/src/gist_tle.c @@ -327,6 +327,10 @@ gist_tle_consistent(PG_FUNCTION_ARGS) * gist_tle_union -- compute 2-D bounding box for a set of entries * * The union is [min(alt_low), max(alt_high)] x [min(inc_low), max(inc_high)]. + * + * GiST convention: entryvec->vector[] is 1-based (FirstOffsetNumber), + * vector[0] is unused. entryvec->n includes the unused slot, so + * valid indices are 1 .. entryvec->n - 1. */ Datum gist_tle_union(PG_FUNCTION_ARGS) @@ -338,10 +342,10 @@ gist_tle_union(PG_FUNCTION_ARGS) tle_orbital_key *cur; result = (tle_orbital_key *) palloc(sizeof(tle_orbital_key)); - cur = (tle_orbital_key *) DatumGetPointer(entryvec->vector[0].key); + cur = (tle_orbital_key *) DatumGetPointer(entryvec->vector[FirstOffsetNumber].key); *result = *cur; - for (i = 1; i < entryvec->n; i++) + for (i = FirstOffsetNumber + 1; i < entryvec->n; i++) { cur = (tle_orbital_key *) DatumGetPointer(entryvec->vector[i].key); key_merge(result, cur); @@ -413,35 +417,43 @@ picksplit_cmp(const void *a, const void *b) * Standard R-tree approach: compute spread in both dimensions, split * along whichever dimension has the greater spread. This prevents * the tree from becoming biased toward one dimension. + * + * GiST convention: entryvec->vector[] is 1-based (FirstOffsetNumber), + * vector[0] is unused/uninitialized. entryvec->n includes the unused + * slot, so the actual entry count is (entryvec->n - 1) and valid + * indices are FirstOffsetNumber .. entryvec->n - 1. The OffsetNumbers + * placed into spl_left[] and spl_right[] must also be 1-based. */ Datum gist_tle_picksplit(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); GIST_SPLITVEC *splitvec = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); - int nentries = entryvec->n; + OffsetNumber maxoff = entryvec->n - 1; + int nentries = maxoff - FirstOffsetNumber + 1; picksplit_item *items; tle_orbital_key *left_union; tle_orbital_key *right_union; tle_orbital_key *cur; int split_at; int i; + OffsetNumber off; double alt_min, alt_max, inc_min, inc_max; double alt_spread, inc_spread; bool split_on_alt; /* First pass: compute spread in both dimensions */ - cur = (tle_orbital_key *) DatumGetPointer(entryvec->vector[0].key); + cur = (tle_orbital_key *) DatumGetPointer(entryvec->vector[FirstOffsetNumber].key); alt_min = (cur->alt_low + cur->alt_high) / 2.0; alt_max = alt_min; inc_min = (cur->inc_low + cur->inc_high) / 2.0; inc_max = inc_min; - for (i = 1; i < nentries; i++) + for (off = FirstOffsetNumber + 1; off <= maxoff; off++) { double alt_mid, inc_mid; - cur = (tle_orbital_key *) DatumGetPointer(entryvec->vector[i].key); + cur = (tle_orbital_key *) DatumGetPointer(entryvec->vector[off].key); alt_mid = (cur->alt_low + cur->alt_high) / 2.0; inc_mid = (cur->inc_low + cur->inc_high) / 2.0; @@ -462,10 +474,10 @@ gist_tle_picksplit(PG_FUNCTION_ARGS) /* Second pass: compute sort values in the chosen dimension */ items = (picksplit_item *) palloc(sizeof(picksplit_item) * nentries); - for (i = 0; i < nentries; i++) + for (i = 0, off = FirstOffsetNumber; off <= maxoff; i++, off++) { - cur = (tle_orbital_key *) DatumGetPointer(entryvec->vector[i].key); - items[i].index = i; + cur = (tle_orbital_key *) DatumGetPointer(entryvec->vector[off].key); + items[i].index = off; /* store 1-based OffsetNumber directly */ if (split_on_alt) items[i].sortval = (cur->alt_low + cur->alt_high) / 2.0; else @@ -476,7 +488,7 @@ gist_tle_picksplit(PG_FUNCTION_ARGS) split_at = nentries / 2; - /* Allocate offset arrays (GiST uses OffsetNumber, 1-based) */ + /* Allocate offset arrays */ splitvec->spl_left = (OffsetNumber *) palloc(sizeof(OffsetNumber) * nentries); splitvec->spl_right = (OffsetNumber *) palloc(sizeof(OffsetNumber) * nentries); splitvec->spl_nleft = 0; @@ -497,21 +509,19 @@ gist_tle_picksplit(PG_FUNCTION_ARGS) for (i = 0; i < nentries; i++) { - int idx = items[i].index; + OffsetNumber idx = items[i].index; /* already 1-based */ cur = (tle_orbital_key *) DatumGetPointer( entryvec->vector[idx].key); if (i < split_at) { - splitvec->spl_left[splitvec->spl_nleft++] = - (OffsetNumber)(idx + 1); /* 1-based */ + splitvec->spl_left[splitvec->spl_nleft++] = idx; key_merge(left_union, cur); } else { - splitvec->spl_right[splitvec->spl_nright++] = - (OffsetNumber)(idx + 1); + splitvec->spl_right[splitvec->spl_nright++] = idx; key_merge(right_union, cur); } } diff --git a/src/spgist_tle.c b/src/spgist_tle.c index 0fcfacc..eb41c3c 100644 --- a/src/spgist_tle.c +++ b/src/spgist_tle.c @@ -584,22 +584,18 @@ spgist_tle_inner_consistent(PG_FUNCTION_ARGS) if (have_query && level == 0) { /* - * L0: SMA pruning. - * bin_low is the SMA of the lowest object in this bin at - * index build time. Later inserts with lower SMA route to - * bin 0, so for the first bin we use AE (physical minimum - * SMA) to avoid false negatives. + * L0: SMA range narrowing only — no altitude pruning. * - * Conservative: assume e=0 (circular, worst case for - * "too high" pruning -- circular has highest perigee for - * a given SMA). + * We cannot prune SMA bins by altitude because eccentricity + * is not available at the inner node level. A satellite + * at SMA 70,000 km with e=0.88 has perigee ~2,000 km — + * well within typical max_alt. Without knowing e, any SMA + * bin could contain satellites with perigee near Earth's + * surface. + * + * L0 still helps by narrowing the SMA range passed to L1 + * for computing a tighter ground footprint. */ - double effective_low = (i == 0) ? WGS72_AE : bin_low; - double perigee_alt = effective_low - WGS72_AE; - double max_alt = max_visible_altitude_km(win.min_el_deg); - - if (perigee_alt > max_alt) - dominated = true; } else if (have_query && level == 1) { @@ -789,7 +785,7 @@ spgist_tle_leaf_consistent(PG_FUNCTION_ARGS) /* - * tle_visibility_possible(observer_window, tle) -> bool + * tle_visibility_possible(tle, observer_window) -> bool * * Standalone operator: can the satellite possibly be visible from * this observer during this time window? Combines altitude check, @@ -797,12 +793,16 @@ spgist_tle_leaf_consistent(PG_FUNCTION_ARGS) * * This is the same logic as leaf_consistent, callable directly * as a SQL operator for sequential scans or WHERE clauses. + * + * The indexed column (tle) MUST be the left argument so that + * PostgreSQL can form a ScanKey and pass it to inner_consistent + * for tree-level pruning. See skey.h:23-26. */ Datum tle_visibility_possible(PG_FUNCTION_ARGS) { - HeapTupleHeader composite = PG_GETARG_HEAPTUPLEHEADER(0); - pg_tle *tle = (pg_tle *) PG_GETARG_POINTER(1); + pg_tle *tle = (pg_tle *) PG_GETARG_POINTER(0); + HeapTupleHeader composite = PG_GETARG_HEAPTUPLEHEADER(1); ObserverWindow win; extract_observer_window(composite, &win); diff --git a/test/expected/spgist_tle.out b/test/expected/spgist_tle.out index 8e45528..c102870 100644 --- a/test/expected/spgist_tle.out +++ b/test/expected/spgist_tle.out @@ -42,12 +42,12 @@ INSERT INTO test_spgist (name, tle) VALUES ('GEO-SAT', -- specific 2-hour window (correct physics, see Test 5 for 24h). -- ============================================================ SELECT name, - ROW( + tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-01 02:00:00+00'::timestamptz, 10.0 - )::observer_window &? tle AS visible + )::observer_window AS visible FROM test_spgist WHERE name = 'ISS'; name | visible @@ -60,12 +60,12 @@ WHERE name = 'ISS'; -- 5 deg inc + ~12 deg footprint = 17 deg < 43.7 deg latitude -- ============================================================ SELECT name, - ROW( + tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-01 02:00:00+00'::timestamptz, 10.0 - )::observer_window &? tle AS visible + )::observer_window AS visible FROM test_spgist WHERE name = 'Equatorial-LEO'; name | visible @@ -82,12 +82,12 @@ CREATE INDEX test_spgist_idx ON test_spgist USING spgist (tle tle_spgist_ops); SET enable_seqscan = off; SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('0.0N 0.0E 0m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-01 02:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; name --------- @@ -103,12 +103,12 @@ SET enable_indexscan = off; SET enable_bitmapscan = off; SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('0.0N 0.0E 0m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-01 02:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; name --------- @@ -125,12 +125,12 @@ RESET enable_bitmapscan; -- ============================================================ SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; name --------- @@ -144,12 +144,12 @@ ORDER BY name; -- ============================================================ SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 45.0 -)::observer_window &? tle +)::observer_window ORDER BY name; name --------- @@ -174,12 +174,12 @@ WHERE a.name = 'ISS' AND b.name = 'Hubble'; SET enable_seqscan = off; SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; name --------- @@ -194,12 +194,12 @@ RESET enable_seqscan; INSERT INTO test_spgist (name, tle) VALUES ('NULL-SAT', NULL); SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; name --------- @@ -214,12 +214,12 @@ INSERT INTO test_spgist (name, tle) VALUES ('DECAYED', '1 99904U 24999D 24001.50000000 .00000000 00000+0 00000+0 0 9993 2 99904 0.0000 0.0000 0000000 0.0000 0.0000 0.00000000 00001'); SELECT name, - ROW( + tle &? ROW( observer('0.0N 0.0E 0m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 - )::observer_window &? tle AS visible + )::observer_window AS visible FROM test_spgist WHERE name = 'DECAYED'; name | visible @@ -234,12 +234,12 @@ WHERE name = 'DECAYED'; -- ============================================================ SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('90.0N 0.0E 0m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; name --------- @@ -251,12 +251,12 @@ ORDER BY name; -- overhead at the instant. RAAN window = footprint only. -- ============================================================ SELECT name, - ROW( + tle &? ROW( observer('0.0N 0.0E 0m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-01 00:00:00+00'::timestamptz, 10.0 - )::observer_window &? tle AS visible + )::observer_window AS visible FROM test_spgist WHERE name = 'ISS'; name | visible @@ -271,12 +271,12 @@ WHERE name = 'ISS'; SET enable_seqscan = off; SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; name --------- @@ -289,12 +289,12 @@ SET enable_indexscan = off; SET enable_bitmapscan = off; SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; name --------- diff --git a/test/sql/spgist_tle.sql b/test/sql/spgist_tle.sql index c3fc4d8..30bf03a 100644 --- a/test/sql/spgist_tle.sql +++ b/test/sql/spgist_tle.sql @@ -51,12 +51,12 @@ INSERT INTO test_spgist (name, tle) VALUES ('GEO-SAT', -- specific 2-hour window (correct physics, see Test 5 for 24h). -- ============================================================ SELECT name, - ROW( + tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-01 02:00:00+00'::timestamptz, 10.0 - )::observer_window &? tle AS visible + )::observer_window AS visible FROM test_spgist WHERE name = 'ISS'; @@ -66,12 +66,12 @@ WHERE name = 'ISS'; -- 5 deg inc + ~12 deg footprint = 17 deg < 43.7 deg latitude -- ============================================================ SELECT name, - ROW( + tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-01 02:00:00+00'::timestamptz, 10.0 - )::observer_window &? tle AS visible + )::observer_window AS visible FROM test_spgist WHERE name = 'Equatorial-LEO'; @@ -87,12 +87,12 @@ SET enable_seqscan = off; SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('0.0N 0.0E 0m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-01 02:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; RESET enable_seqscan; @@ -107,12 +107,12 @@ SET enable_bitmapscan = off; SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('0.0N 0.0E 0m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-01 02:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; RESET enable_indexscan; @@ -127,12 +127,12 @@ RESET enable_bitmapscan; -- ============================================================ SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; @@ -142,12 +142,12 @@ ORDER BY name; -- ============================================================ SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 45.0 -)::observer_window &? tle +)::observer_window ORDER BY name; @@ -165,12 +165,12 @@ WHERE a.name = 'ISS' AND b.name = 'Hubble'; SET enable_seqscan = off; SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; RESET enable_seqscan; @@ -182,12 +182,12 @@ INSERT INTO test_spgist (name, tle) VALUES ('NULL-SAT', NULL); SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; @@ -199,12 +199,12 @@ INSERT INTO test_spgist (name, tle) VALUES ('DECAYED', 2 99904 0.0000 0.0000 0000000 0.0000 0.0000 0.00000000 00001'); SELECT name, - ROW( + tle &? ROW( observer('0.0N 0.0E 0m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 - )::observer_window &? tle AS visible + )::observer_window AS visible FROM test_spgist WHERE name = 'DECAYED'; @@ -216,12 +216,12 @@ WHERE name = 'DECAYED'; -- ============================================================ SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('90.0N 0.0E 0m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; @@ -230,12 +230,12 @@ ORDER BY name; -- overhead at the instant. RAAN window = footprint only. -- ============================================================ SELECT name, - ROW( + tle &? ROW( observer('0.0N 0.0E 0m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-01 00:00:00+00'::timestamptz, 10.0 - )::observer_window &? tle AS visible + )::observer_window AS visible FROM test_spgist WHERE name = 'ISS'; @@ -247,12 +247,12 @@ WHERE name = 'ISS'; SET enable_seqscan = off; SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; RESET enable_seqscan; @@ -260,12 +260,12 @@ SET enable_indexscan = off; SET enable_bitmapscan = off; SELECT name FROM test_spgist -WHERE ROW( +WHERE tle &? ROW( observer('43.6977N 116.3535W 760m'), '2024-01-01 00:00:00+00'::timestamptz, '2024-01-02 00:00:00+00'::timestamptz, 10.0 -)::observer_window &? tle +)::observer_window ORDER BY name; RESET enable_indexscan; RESET enable_bitmapscan;