Skip to content

TUR-302: Cypher: order points and take their min, max and average - #1339

Merged
rjb32 merged 11 commits into
mainfrom
remyboutonnet/tur-302-7-point-order-and-aggregates
Nov 6, 2026
Merged

rjb32 merged 11 commits into
mainfrom
remyboutonnet/tur-302-7-point-order-and-aggregates

Conversation

@rjb32

@rjb32 rjb32 commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Order points and take their min, max and average.

@rjb32

rjb32 commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor Author

Note

AI-generated summary.

Summary

Goal. Points compare with <, <=, > and >=, and take min, max and avg: MATCH (n:City) RETURN min(n.at), max(n.at), avg(n.at).

Approach. The comparison operators follow ORDER BY's total order: SRID, then x, y and z, across CRSs too. Neo4j instead answers null for < between two different points. min and max use that order everywhere: plain, per group, DISTINCT, and over tagged cells. avg is the coordinate-wise centroid of points of one CRS. It is held as a running mean (Point::addToMean), so the accumulator is always a valid Point; a running sum of latitudes would fail the [-90, 90] check. Points of two CRSs, or points mixed with numbers, raise.

Where to look.

  • storage/metadata/Point.cpp:590 Point::addToMean
  • query/ir/exec/NLExecutor.cpp:3491 addToAverageTotal: the count the running mean needs, threaded through the typed folds
  • query/ir/exec/NLExecutor.cpp:4034 NLTaggedSum::addPoint: the same for tagged cells
  • query/AST/decl/EvaluatedType.h:365 orderClassOf: points now have an order class
point({x:1,y:9}) < point({x:2,y:0})              true
point({x:9,y:9,crs:'wgs-84'}) < point({x:0,y:0}) true    4326 < 7203
point({x:1,y:2}) < 3                             null
avg([(0,0), (4,0), (2,6)])                       point({x: 2.0, y: 2.0, crs: 'cartesian'})

Evidence

  • Before: < between points is null, and min, max and avg reject points.
    After:
    test_query_ir_point_order_and_aggregate   [  PASSED  ] 17 tests.
    ctest                                     100% tests passed, 0 tests failed out of 1169
    

Merge Danger

Door: two-way

Blast Radius: query

A geographic centroid is a plain mean of longitudes and latitudes, so points on both sides of the 180th meridian average to a longitude near 0. docs/points.md says so.

@rjb32
rjb32 added this pull request to stack #1347 November 5, 2026 22:38
@rjb32
rjb32 force-pushed the remyboutonnet/tur-302-6-geoparquet-points branch from 1b95815 to 01a03cc Compare November 6, 2026 09:22
@rjb32
rjb32 force-pushed the remyboutonnet/tur-302-7-point-order-and-aggregates branch from b09ce0b to 6791b61 Compare November 6, 2026 09:23
@rjb32
rjb32 force-pushed the remyboutonnet/tur-302-6-geoparquet-points branch from 01a03cc to c691527 Compare November 6, 2026 15:59
@rjb32
rjb32 force-pushed the remyboutonnet/tur-302-7-point-order-and-aggregates branch from 6791b61 to 0437cf6 Compare November 6, 2026 15:59
@rjb32
rjb32 force-pushed the remyboutonnet/tur-302-7-point-order-and-aggregates branch from 0437cf6 to e75b0f1 Compare November 6, 2026 19:19
@rjb32
rjb32 force-pushed the remyboutonnet/tur-302-6-geoparquet-points branch from c691527 to 57e2a5d Compare November 6, 2026 19:19
@rjb32
rjb32 removed this pull request from stack #1347 November 6, 2026 19:36
@rjb32
rjb32 changed the base branch from remyboutonnet/tur-302-6-geoparquet-points to main November 6, 2026 19:37
@rjb32
rjb32 merged commit e75b0f1 into main Nov 6, 2026
2 of 4 checks passed
@rjb32
rjb32 deleted the remyboutonnet/tur-302-7-point-order-and-aggregates branch November 6, 2026 19:37
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.

1 participant