Skip to content

Prefetch references without getters on custom row classes - #3877

Closed
ybai08 wants to merge 1 commit into
simolus3:developfrom
ybai08:fix/3437-prefetch-custom-row-class
Closed

ybai08 wants to merge 1 commit into
simolus3:developfrom
ybai08:fix/3437-prefetch-custom-row-class

Conversation

@ybai08

@ybai08 ybai08 commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

Closes #3437

When a table uses a custom row class that doesn't have a getter for a column that references another table, prefetching the reverse reference generates code that doesn't compile. The generated getPrefetchedDataCallback matches the prefetched rows to their parent with the row classes' getters:

referencedItemsForCurrentItem: (item, referencedItems) =>
    referencedItems.where((e) => e.group == item.id),

With @UseRowClass(Member) on a Members table whose Member class only has id, the build fails with:

Error: The getter 'group' isn't defined for the type 'Member'.

5ecc9a7 already fixed this for forward references ($_itemColumn reads the column from the TypedResult). This PR does the same for prefetched reverse references.

Change

  • drift: a new $_getPrefetchedDataByColumns helper next to $_getPrefetchedData. It runs the same combined query, but through buildSelectStatement(), so it gets TypedResults. It groups the referenced rows by the raw value of the referencing column and looks up each current row by the raw value of the referenced column. Both columns are passed by their SQL name and resolved with columnsByName, the same way $_itemColumn does it. $_getPrefetchedData is unchanged, so code generated by older drift_dev versions keeps working.
  • drift_dev: outside the drift3 preview, the manager writer emits $_getPrefetchedDataByColumns with currentColumn / referencedColumn (and the referenced table class as a fourth type argument) in place of the referencedItemsForCurrentItem closure. The drift3 path is unchanged (more on that below).
  • Regenerated drift/test/generated/todos.g.dart and drift/example/main.g.dart. I didn't regenerate the docs snippets or the other examples. They still call $_getPrefetchedData, which still exists.
  • Changelog entries for drift and drift_dev.

Tests

New drift/test/integration_tests/regress_3437_test.dart (with its generated part file): a Groups table and a Members table with a custom row class that has no getter for the group column. It checks:

  • prefetching membersRefs from groups returns the right members per group. On develop the generated file doesn't compile (the error above), so the test fails to load;
  • reading the forward group reference from members works. This already passes on develop (since 5ecc9a7) and is there as a regression guard. It's also the case from Table primary composite key from Foreign Keys fails in 2.20 #3173, which looks fixed on develop already.

The existing manager prefetch tests (drift/test/manager/manager_prefetch_test.dart) now run through the new helper because todos.g.dart was regenerated.

What I ran locally (Dart 3.13.5, macOS arm64). The workspace includes Flutter packages and I didn't have Flutter installed, so I ran dart pub get with the root workspace temporarily cut down to drift, drift_dev, sqlparser, future/* and the two testcase packages. That change is not part of the PR.

  • drift: dart run build_runner build --delete-conflicting-outputs (no changes to committed files after the commit), dart format -o none --set-exit-if-changed ., dart analyze --fatal-infos --fatal-warnings, DID_RUN_BUILD_RUNNER=1 dart test --preset ci_unit_tests: 931 passed, 4 skipped.
  • drift_dev: format and analyze clean, dart test: 512 passed, 1 skipped.
  • sqlparser: dart test: 753 passed.
  • future/drift_manager: dart test: 35 passed.

Not run: browser/wasm tests, the Flutter packages, and the docs build.

Notes

  • Generated code from this drift_dev needs a drift that has $_getPrefetchedDataByColumns. drift_dev currently allows drift: ">=2.30.0 <2.36.0", so the lower bound needs to go up when this is released. I left that for the release, as with the other constraint bumps.
  • drift3 preview: ManagerResultRow is built differently, so I kept the existing closure there. Custom row classes without these getters will still fail to compile with drift3. I can port the helper to drift_manager if you want it in the same PR.
  • Matching uses the columns' SQL values (before type converters) on both sides, so a relation whose columns use the same converter still matches. The manager writer already drops relations where the two column types differ.

Generated managers matched prefetched reverse references by reading
the referencing column through getters on the row classes, which custom
row classes don't have to declare. The generated code then failed to
compile. Match the rows by their raw column values instead.

Closes simolus3#3437
@simolus3

Copy link
Copy Markdown
Owner

Thanks for the contribution! I have merged your commit in 8e3cc33 and ported this to drift3 as well 👍

@simolus3 simolus3 closed this Oct 19, 2026
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.

Manager references around custom row classes throws an error when calling prefetchedData

2 participants