Skip to content

fix: Preserve relationship fields on queries that filter via JOIN or subquery#2149

Merged
ferenc-csaky merged 1 commit into
mainfrom
fix/2148-preserve-relationships-join-subquery
Jun 16, 2026
Merged

fix: Preserve relationship fields on queries that filter via JOIN or subquery#2149
ferenc-csaky merged 1 commit into
mainfrom
fix/2148-preserve-relationships-join-subquery

Conversation

@velo

@velo velo commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #2148.

A nested relationship field (e.g. Thing.detail) was only carried onto a query when that query was a clean passthrough (SELECT * FROM Table WHERE <flat predicate>). As soon as the body used a JOIN or subquery, the compiler synthesized a new result type named after the query containing only the projected scalar columns and silently dropped every relationship/nested field.

Root cause

In SQRLLogicalPlanAnalyzer, base-table detection — which decides whether a query reuses the source table's GraphQL type (keeping its relationship fields) or synthesizes a fresh scalar-only type — only inspected the last source table via Iterables.getLast(sourceTables).

For a clean passthrough the only source is the base table, so it matched. But with a JOIN/subquery filter, the right-most source is the filter table (e.g. Tombstone), whose row type doesn't match the projected result — so no base table was found and the relationship fields were dropped.

Fix

Scan the source tables in reverse and pick the right-most one whose row type matches the result, instead of checking only the last one. This matches the existing code comment ("the right-most table in the relational tree that has the same type as the result"), so a JOIN/subquery used purely as a filter now correctly resolves back to the projected base table and preserves its relationship fields.

Tests

  • New self-contained usecase relationship-filter reproducing the issue (clean / subquery / anti-join queries over a Thing.detail relationship). Its snapshot confirms all three now return [Thing!] with detail retained.
  • Updated the pre-existing DAGPlannerTest/subqueryTest snapshot, which was itself capturing the buggy behavior: AdminOrderCustomers (SELECT c.* FROM Customer ... NOT EXISTS subquery) and CustomerWithOrders (... WHERE EXISTS(...)) now correctly reuse the Customer type instead of generating duplicate types.

Verification: UseCaseCompileTest (61), DAGPlannerTest (90), and all sqrl-planner unit tests (257) pass. Across all those snapshots only subqueryTest changed — a small, intended blast radius.

…subquery

Signed-off-by: Marvin Froeder <marvin@datasqrl.com>
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 14.67%. Comparing base (c6ab93b) to head (7bf04e5).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...sqrl/planner/analyzer/SQRLLogicalPlanAnalyzer.java 0.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #2149      +/-   ##
============================================
- Coverage     14.67%   14.67%   -0.01%     
  Complexity      909      909              
============================================
  Files           607      607              
  Lines         17515    17516       +1     
  Branches       2125     2125              
============================================
  Hits           2571     2571              
- Misses        14702    14703       +1     
  Partials        242      242              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@ferenc-csaky ferenc-csaky added the bug Something isn't working label Jun 16, 2026
@ferenc-csaky ferenc-csaky added this to the 0.10.7 milestone Jun 16, 2026
@ferenc-csaky ferenc-csaky merged commit 2ccaeeb into main Jun 16, 2026
16 checks passed
@ferenc-csaky ferenc-csaky deleted the fix/2148-preserve-relationships-join-subquery branch June 16, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Relationship/nested fields dropped from a query that uses JOIN or subquery (preserved on clean SELECT *)

2 participants