Skip to content

storage: fail fast on foreign rel traversal; exclude scan-backed rels from CountRelTable - #844

Merged
adsharma merged 2 commits into
mainfrom
foreign-rel-safety
Aug 27, 2026
Merged

storage: fail fast on foreign rel traversal; exclude scan-backed rels from CountRelTable#844
adsharma merged 2 commits into
mainfrom
foreign-rel-safety

Conversation

@adsharma

Copy link
Copy Markdown
Contributor

Fixes a segfault and a silent wrong-count found by the duckdb extension rel auto-detection tests (LadybugDB/extensions#65, duckdb_rel branch).

MATCH traversal over a foreign-backed rel table (RelGroupCatalogEntry with a scan function — the auto-detected rel_* / csr_rel_* tables) cannot work yet: the extend pipeline expects lbug internal node IDs while the foreign scan produces raw foreign-key values, and the FK→internal-ID mapping layer is not implemented (tracked as deferred work for pg_client too). Scanning through the mis-wired vectors segfaulted.

  • ForeignRelTable::scanInternal now throws a clear RuntimeException instead. Queries rewritten by the foreign join push-down optimizer never reach this path.
  • CountRelTableOptimizer no longer rewrites count plans over scan-backed rel groups: ForeignRelTable::getNumTotalRows is a stub returning 0, which silently produced wrong counts.
  • CountRelTable guards ForeignRelTable at execution time as defense-in-depth.

Verified: duckdb_rel e2e cases pass; 249 tinysnb/multihop main tests pass.

… from CountRelTable

MATCH traversal over a foreign-backed rel table (RelGroupCatalogEntry with
a scan function, e.g. duckdb/pg_client auto-detected rel_* tables) cannot
work yet: the extend pipeline expects internal node IDs while the scan
produces raw foreign-key values, and the FK-to-internal-ID mapping layer is
not implemented. Scanning through the mis-wired vectors segfaulted.

- ForeignRelTable::scanInternal now throws a clear RuntimeException
  instead of crashing. Queries handled by the foreign join push-down
  optimizer never reach this path.
- CountRelTableOptimizer no longer rewrites count plans over scan-backed
  rel groups (RelTable::getNumTotalRows is a stub returning 0 for them,
  which silently produced wrong counts).
- CountRelTable also guards ForeignRelTable at execution time as
  defense-in-depth.
…ling

ForeignRelTable::scanInternal: when the bound scan bind data carries
src/dst scan column positions (the csr_rel_* contract: foreign keys
usable as node offsets by design), wrap raw FK values into
internalID_t{offset=fkValue, tableID=nbrTableID} and emit rows through
the foreign scan, filtering by the current bound-node batch. Tables
without the contract keep failing fast.

Also fixes traversal routing for foreign attached databases:
- resolveTableStorage: fall through to main-path resolution for
  non-LBUG attached DBs instead of throwing (shadow entries own ID
  uniqueness; data lives in the foreign DB).
- ForeignJoinPushDownOptimizer: normalize rel foreignDatabaseName to
  the "db(TYPE)" node-name format so the same-database pattern check
  passes for both DDL-created ("db(TYPE)") and extension-registered
  (raw) name shapes.
@adsharma
adsharma force-pushed the foreign-rel-safety branch from c462196 to 7995eb3 Compare August 27, 2026 23:56
@adsharma
adsharma merged commit cef5f66 into main Aug 27, 2026
4 checks passed
@adsharma
adsharma deleted the foreign-rel-safety branch August 27, 2026 23:56
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