ST_Intersects pushdown: vortex.geo.intersects kernel, DuckDB lowering, spatial function overrides#8704
Open
HarukiMoriarty wants to merge 5 commits into
Open
ST_Intersects pushdown: vortex.geo.intersects kernel, DuckDB lowering, spatial function overrides#8704HarukiMoriarty wants to merge 5 commits into
HarukiMoriarty wants to merge 5 commits into
Conversation
Merging this PR will improve performance by 10.86%
Performance Changes
Tip Curious why this is faster? Comment Comparing Footnotes
|
myrrc
requested changes
Jul 10, 2026
Contributor
|
Let's add a sqllogictest which checks our queries don't break if we override the functions |
32dd2cc to
8cfcef6
Compare
…, spatial overrides
vortex-geo gains a GeoIntersects kernel (OGC semantics: not disjoint,
boundary contact counts; the function id is kept stable so a future
stats-pruning rewrite can key on it). Kernels stay thin
materialize-and-delegate wrappers over geo: GeoDistance's columnar point
fast paths are removed as well, since geo computes row by row and
hand-rolled columnar paths belong in a future columnar geometry compute
library (noted in scalar_fn/mod.rs).
vortex-duckdb lowers two-argument st_intersects like st_distance, and
shadows the spatial functions whose registrations block filter pushdown:
st_intersects is marked fallible, which DuckDB will not push through a
view's projection, and st_dwithin folds its radius into bind data. The
overrides live in their own translation unit
(cpp/spatial_overrides.{hpp,cpp}) as a (name, arity, tweak) table shared
by registration and the join-condition restore pass, keeping
scalar_fn_pushdown.* free of spatial code. e2e tests cover every lowered
geo filter on a direct file scan and through a view.
Signed-off-by: Nemo Yu <zyu379@wisc.edu>
8cfcef6 to
25a839e
Compare
myrrc
approved these changes
Jul 10, 2026
The C declaration moves to spatial_overrides.h, which bindgen consumes alongside the other C API headers, and SpatialOverrideRestore is declared in spatial_overrides.hpp with its methods implemented in the .cpp, matching scalar_fn_pushdown's layout. Signed-off-by: Nemo Yu <zyu379@wisc.edu>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rationale for this change
ST_Intersectsover native geometry columns currently evaluates inside DuckDB, exporting every row asGEOMETRYjust to be tested. This adds a nativevortex.geo.intersectskernel and pushes the filter into the scan: on SpatialBench SF1 (6M points vs a literal polygon), 406ms (DuckDB filter) / 36.6ms (SPATIAL_JOIN) -> 12.4ms pushed. Part of the native geospatial lane, following theST_Distance/ST_DWithinpushdown.What changes are included in this PR?
vortex-geo:GeoIntersectskernel.vortex-duckdb: lowerst_intersects(native column, GEOMETRY literal)likest_distance.vortex-duckdb: shadow spatial'sST_Intersectswith a non-fallible copy — DuckDB won't push can-throw filters through the projection every view-registered table has. TheST_DWithinoverride generalizes into a table-driven registry (spatial_overrides.hpp) shared by registration and the join-condition restore pass.Note: drop
GeoDistance's columnar point fast paths.geois row-oriented, so kernels materialize rows regardless; hand-rolled columnar paths belong in a future columnar geometry compute library (pushed Q1: 5.4ms -> 12.6ms, still far ahead of unpushed).