Skip to content

feat(query): build a join query from the foreign keys between tables - #3763

Merged
datlechin merged 5 commits into
mainfrom
feat/2531-visual-join-builder
Oct 21, 2026
Merged

datlechin merged 5 commits into
mainfrom
feat/2531-visual-join-builder

Conversation

@datlechin

@datlechin datlechin commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Summary

  • New sheet, Database > Build Join Query…: pick tables, each joins the earlier ones on the cheapest chain of foreign keys.
  • A junction table between a many-to-many pair is added automatically; a junction or chain wins over two tables that only share a parent.
  • A table no key reaches is cross joined, and the sheet says so.
  • Per table: Inner or Left Join, and a picker of every key to an earlier table, or none.
  • Column checkboxes replace SELECT *.
  • Filters reuse the filter bar's operators and FilterSQLGenerator, so values are typed and escaped the same way.
  • Live SQL preview, quoted by the connection's driver; tables outside the engine's implicit schema are schema-qualified, as the browse query does.
  • Open in Query Tab writes the SQL into a new query tab on that database.
  • ER diagram: Command- or Shift-click adds a table to the selection.
  • ER diagram: the new toolbar button, or Build Join Query… in a table's or column's context menu, opens the builder on the selection.
  • The menu item sits after Open Table and Show Structure, so destructive items stay last; a right-click inside a multiple selection keeps it.
  • With the diagram focused, the Database menu command uses the diagram's selection (responder chain); otherwise the sidebar's selected tables.
  • ER selection is an ordered list instead of one optional id; tests that built a scene with selectedNodeId: now pass selectedNodeIds:.
  • Keys spelled in another case than the catalog (SQLite reports parent(id) for table Parent) resolve to the catalog name; the ER diagram dropped that edge before.
  • The ER diagram no longer draws a key into another schema to a same-named table of its own schema.
  • Enabled for engines with SQL and foreign keys; off in Agent mode like the other browse commands.
  • Docs: docs(features): document the join builder docs#113

Test plan

  • JoinGraphTests, JoinQueryDraftTests, JoinQuerySQLWriterTests: paths, relinking, SQL per dialect, LEFT and CROSS joins, columns, WHERE escaping, schema qualification.
  • JoinBuilderOpeningTests: new tab on the builder's database, sidebar seeding keeps one schema.
  • ERDiagramPointerInputTests: Command/Shift-click, right-click menu, disabled command, multi-selection accessibility. Its fixture offers no join builder unless a test asks, so the diagram menu tests keep their expectations.
  • ERDiagramGraphBuilderTests, ERDiagramViewModelLoadTests, ForeignKeyTargetScopeTests: case-mismatched reference keeps its edge, key into another schema is not drawn.
  • MainMenuBuilderTests: menu enablement.
  • UI: JoinBuilderUITests picks album and artist on the fixture's diagram and reads the join on album.artist_id = artist.id, quoted the SQLite driver's way, in the new tab.

Screenshots

No join builder existed before.

Build Join Query, light
Build Join Query, dark
Two tables selected on the ER diagram, light
Two tables selected on the ER diagram, dark

Fixes #2531

…-builder

# Conflicts:
#	apple/TablePro/Resources/Localizable.xcstrings
@datlechin
datlechin enabled auto-merge (squash) October 21, 2026 16:11
…-builder

# Conflicts:
#	apple/TablePro/Resources/Localizable.xcstrings
#	apple/TablePro/Views/Main/MainContentCoordinator.swift
#	apple/TablePro/Views/Main/MainContentView.swift
…-builder

# Conflicts:
#	apple/TablePro/ViewModels/ERDiagramViewModel.swift
#	apple/TablePro/Views/ERDiagram/ERDiagramScene.swift
#	apple/TablePro/Views/ERDiagram/ERDiagramSceneView.swift
#	apple/TablePro/Views/ERDiagram/ERDiagramToolbar.swift
#	apple/TablePro/Views/ERDiagram/ERDiagramView.swift
#	apple/TablePro/Views/Main/Child/MainEditorContentView.swift
#	apple/TableProTests/Helpers/ERDiagramLoadFixture.swift
#	apple/TableProTests/Views/ERDiagram/ERDiagramPointerInputTests.swift
@datlechin
datlechin merged commit 8847af8 into main Oct 21, 2026
9 checks passed
@datlechin
datlechin deleted the feat/2531-visual-join-builder branch October 22, 2026 07:05
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.

Visual join builder

1 participant