Skip to content

fix(postgres): let distanceLessThan use the spatial index - #1001

Merged
HarshMN2345 merged 1 commit into
mainfrom
fix/postgres-distance-index
Oct 7, 2026
Merged

HarshMN2345 merged 1 commit into
mainfrom
fix/postgres-distance-index

Conversation

@HarshMN2345

Copy link
Copy Markdown
Member

What does this PR do?

distanceLessThan compiled to ST_Distance(...) < :distance. PostGIS cannot answer that from a GIST index, so a radius query filtered every row while walking the primary key, and got slower the fewer rows matched (appwrite/appwrite#14177).

  • Without meters: ST_DWithin(col, geom, :distance) AND ST_Distance(col, geom) < :distance. ST_DWithin uses the index; ST_Distance keeps the boundary exclusive.
  • With meters, point column and point value: col && ST_Expand(geom, :lon, :lat) AND <unchanged geography ST_Distance>. The box holds every point within range on the WGS84 spheroid: a degree of latitude spans at least 110,574 m, and a degree of longitude at least 111,319 m × cos of the most poleward latitude in range.
  • Unchanged SQL (exact geography comparison only): lines and polygons on either side, since their geodesic edges bulge out of any planar box, and boxes that would reach a pole or the antimeridian.
  • distanceGreaterThan, distanceEqual and distanceNotEqual are unchanged; they cannot use an index.

Test Plan

200,000 points in the issue's layout (~700 × 900 km around [10, 51]) on PostgreSQL 18 + PostGIS 3.6 with the spatial index, limit 25, average of 20 runs:

Query Before After
1 km, meters 188 ms (pkey scan, 199,997 rows removed by filter) 1.2 ms (GIST index scan)
20 km, meters 13.6 ms 1.6 ms
1 km in degrees 30 ms 0.8 ms

Each query returns the same rows as before.

Results were also compared with the old SQL on 100,000 points packed near both poles and the antimeridian. 800 random meter queries (10 m to 1,000 km, half of them centered near a pole or the antimeridian) returned identical rows. Cases that drop rows under a naive degree radius also match: 1 m around [0, 89.999], a point 20 km from the geodesic arc of [[-60, 60], [60, 60]], and a stored line within 20 km of a point.

tests/e2e/Adapter/PostgresTest.php and tests/e2e/Adapter/SharedTables/PostgresTest.php pass. No new test: which plan Postgres picks is not observable through the adapter API, and the existing spatial e2e tests cover the results.

Related

ST_Distance(a, b) < d cannot be served by a GIST index, so radius queries
filtered every row while walking the primary key.

Without meters, distanceLessThan now leads with ST_DWithin on the geometry
column. With meters on a point column and a point value, it leads with a
degree box (&& ST_Expand) that holds every point within range on the WGS84
spheroid. Lines and polygons, and boxes that would reach a pole or the
antimeridian, keep the exact geography comparison only. The exact
ST_Distance check stays in every case, so the boundary remains exclusive.
@coderabbitai

coderabbitai Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 18 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: utopia-php/database/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d2dc84c9-d71f-498d-87fd-163967e93746
📥 Commits

Reviewing files that changed from the base of the PR and between ef5d6e5 and c5fc677.

📒 Files selected for processing (1)
  • src/Database/Adapter/Postgres.php
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@HarshMN2345
HarshMN2345 merged commit 7b750be into main Oct 7, 2026
21 checks passed
@HarshMN2345
HarshMN2345 deleted the fix/postgres-distance-index branch October 7, 2026 16:31
abnegate added a commit that referenced this pull request Oct 8, 2026
… into ws-api-w7

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants