feat(vortex-geo): per-row bounding-box scalar function (vortex.geo.envelope)#8831
feat(vortex-geo): per-row bounding-box scalar function (vortex.geo.envelope)#8831HarukiMoriarty wants to merge 2 commits into
Conversation
Merging this PR will not alter performance
Comparing Footnotes
|
Polar Signals Profiling ResultsLatest Run
Previous Runs (5)
Powered by Polar Signals Cloud |
Benchmarks: Vortex queries 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.059x ➖, 0↑ 0↓)
datafusion / parquet (0.991x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed (1.051x ➖, 0↑ 0↓)
duckdb / parquet (1.014x ➖, 0↑ 0↓)
No file size changes detected. |
488a97c to
0c8823f
Compare
0c8823f to
b269fa9
Compare
connortsui20
left a comment
There was a problem hiding this comment.
this should be a scalar function?
…velope) `GeoEnvelope` computes the per-row 2-D axis-aligned bounding box of a native geometry column, returned as a native geoarrow.box (`Rect`) column — the per-row counterpart of the `GeometryAabb` aggregate (whole-column). Intended for row-oriented consumers such as bulk-loading an in-memory R-tree in a spatial-join operator, which read the resulting box column back row by row. Computed directly over the native coordinate storage — no `geo_types` decode and no Arrow round-trip: walk the nested `ListView` storage down to the leaf x/y buffers, tracking which top-level row owns each coordinate, then min/max per row. A `Rect` input is the identity; a null row or an empty geometry yields a null box, so the output is always nullable. Hoist the shared `f64_field` coordinate-column accessor into `extension::coordinate`, used by both this function and the aggregate. Signed-off-by: Nemo Yu <zyu379@wisc.edu>
b269fa9 to
72aa947
Compare
Benchmarks: PolarSignals Profiling 📖Vortex (geomean): 1.016x ➖ How to read Verdict and Engines
datafusion / vortex-file-compressed (1.016x ➖, 0↑ 0↓)
No file size changes detected. |
🚨🚨🚨❌❌❌ SQL BENCHMARK FAILED ❌❌❌🚨🚨🚨Benchmark |
Benchmarks: TPC-H SF=1 on NVME 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (0.998x ➖, 0↑ 0↓)
datafusion / vortex-compact (0.995x ➖, 0↑ 0↓)
datafusion / parquet (1.016x ➖, 1↑ 4↓)
datafusion / arrow (0.983x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed (0.999x ➖, 0↑ 0↓)
duckdb / vortex-compact (1.004x ➖, 0↑ 0↓)
duckdb / parquet (0.994x ➖, 1↑ 1↓)
duckdb / duckdb (1.006x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: FineWeb NVMe 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.033x ➖, 0↑ 2↓)
datafusion / vortex-compact (1.042x ➖, 0↑ 1↓)
datafusion / parquet (1.024x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed (1.041x ➖, 0↑ 1↓)
duckdb / vortex-compact (1.016x ➖, 0↑ 1↓)
duckdb / parquet (1.038x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: FineWeb S3 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (0.870x ➖, 1↑ 0↓)
datafusion / vortex-compact (1.090x ➖, 0↑ 1↓)
datafusion / parquet (1.031x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed (0.969x ➖, 0↑ 0↓)
duckdb / vortex-compact (0.996x ➖, 0↑ 0↓)
duckdb / parquet (1.026x ➖, 0↑ 0↓)
|
🚨🚨🚨❌❌❌ SQL BENCHMARK FAILED ❌❌❌🚨🚨🚨Benchmark |
Benchmarks: Clickbench Sorted on NVME 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.062x ➖, 0↑ 3↓)
datafusion / parquet (1.061x ➖, 0↑ 3↓)
duckdb / vortex-file-compressed (1.057x ➖, 0↑ 3↓)
duckdb / parquet (1.018x ➖, 0↑ 0↓)
duckdb / duckdb (1.035x ➖, 0↑ 1↓)
File Size Changes (201 files changed, +0.0% overall, 102↑ 99↓)
Totals:
|
Benchmarks: TPC-H SF=10 on NVME 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.008x ➖, 0↑ 0↓)
datafusion / vortex-compact (1.002x ➖, 0↑ 0↓)
datafusion / parquet (0.992x ➖, 0↑ 0↓)
datafusion / arrow (1.009x ➖, 0↑ 1↓)
duckdb / vortex-file-compressed (1.001x ➖, 0↑ 0↓)
duckdb / vortex-compact (1.004x ➖, 0↑ 0↓)
duckdb / parquet (0.990x ➖, 0↑ 0↓)
duckdb / duckdb (0.990x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: Clickbench on NVME 📖Verdict: No clear signal (low confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (0.929x ➖, 19↑ 0↓)
datafusion / parquet (0.958x ➖, 7↑ 0↓)
duckdb / vortex-file-compressed (0.951x ➖, 9↑ 1↓)
duckdb / parquet (0.969x ➖, 4↑ 0↓)
duckdb / duckdb (0.959x ➖, 6↑ 0↓)
File Size Changes (1 files changed, -0.0% overall, 0↑ 1↓)
Totals:
|
Benchmarks: TPC-H SF=1 on S3 📖Verdict: No clear signal (environment too noisy confidence) How to read Verdict and Engines
datafusion / vortex-file-compressed (1.108x ➖, 0↑ 2↓)
datafusion / vortex-compact (1.125x ➖, 0↑ 4↓)
datafusion / parquet (1.084x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed (1.052x ➖, 0↑ 0↓)
duckdb / vortex-compact (1.059x ➖, 0↑ 1↓)
duckdb / parquet (1.039x ➖, 0↑ 0↓)
|
What
Adds
GeoEnvelope(vortex.geo.envelope): the per-row 2-D axis-aligned bounding box of a native geometry column, returned as a nativegeoarrow.box(Rect) column.The consumer is a row-oriented spatial-join operator that bulk-loads an in-memory R-tree (
rstar::RTree::bulk_loadtakes individual objects), so it needs one box per geometry, read back row by row.How
ListViewstorage down to the leaf coordinateStruct, tracking which top-level row owns each coordinate, then min/max x/y per row over the rawf64buffers.Rectinput is the identity (the bounding box of a box is itself).x/yleaf ordinates are read; anyz/mare ignored — matching theGeometryAabbaggregate.validity()returnsNone, since the output null mask is not derivable from the operand's validity (empty geometries introduce nulls even over a non-nullable operand).