feat: add typed table access with PostgrestTable and TableColumn#1634
Draft
spydon wants to merge 6 commits into
Draft
feat: add typed table access with PostgrestTable and TableColumn#1634spydon wants to merge 6 commits into
spydon wants to merge 6 commits into
Conversation
Contributor
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This was referenced Jul 23, 2026
spydon
force-pushed
the
feat/typed-table-access
branch
from
July 23, 2026 11:48
17d12c1 to
6a64143
Compare
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.
What kind of change does this PR introduce?
Feature (draft for design discussion). This is layer 1 of a plan to make query results type-safe so users never have to handle
Map<String, dynamic>. It adds the runtime primitives topostgrestandsupabase; a schema code generator that emits row extension types, table definitions and column tokens is a possible follow-up (layer 2), but everything here is also usable hand-written.What is the current behavior?
Every query resolves to
PostgrestList/PostgrestMap(rawMap<String, dynamic>shapes). The only typing affordance iswithConverter, which can only be applied at the end of a chain, and filters,stream(), and mutations are stringly typed throughout.What is the new behavior?
A typed, opt-in parallel surface next to the existing string-based API (which is unchanged):
PostgrestTable<Row>describes a table plus its row converter;client.table(...)(onPostgrestClient,SupabaseClientandSupabaseQuerySchema) is the typed counterpart offrom(...).TableColumn<Value>carries the column name and value type. Filter methods live on the column (Books.id.eq(5)), because that is the only shape where Dart inference actually rejects a wrong value type;builder.eq(column, value)style would silently infer the common supertype. Text-only filters (like,textSearch, regex) are an extension onTableColumn<String>.where(...)applies aColumnFilter(chain for AND),whereAny([...])builds anor=(...)group with proper quoting, and.not()negates a filter.ColumnFilteris a sealed hierarchy with one class per operator (EqFilter,InListFilter,LikeFilter,RangeLtFilter, ..., grouped under sealed parents likeComparisonFilter), so consumers switch on the filter type itself exhaustively; operator strings only appear at the URL boundary.PostgrestTypedQueryBuilder→PostgrestTypedFilterBuilder→PostgrestTypedTransformBuilder) are thin wrappers around the untyped ones, so all request building, retry, isolate decoding and error handling stays in one place.single(),maybeSingle()andcount()keep the row type (Row,Row?,PostgrestResponse<List<Row>>).stream()gets a typed counterpart emittingList<Row>with typed primary keys and filters (namedfilterbecauseStream.wherealready exists).Extension types over the decoded JSON map are the recommended row representation: conversion is a cast (no per-row parse cost), partial selects and embedded relations work naturally, and unknown columns are ignored. Regular data classes with
fromJsonwork as well.Deliberately not included yet, to keep the surface reviewable: typed
csv/geojson/explain/head/dryRunpassthroughs, typedrpc, typedInsert/Updatevalue types (planned as generated companion types in layer 2), and typed OR composition beyondwhereAny. Dropping tofrom()covers all of these today.Additional context
sdk-compliance.yaml; the symbol, drift and schema checks fromsupabase/sdkpass locally.packages/postgrest/test/typed_query_test.dartverifies eachColumnFilterbuilds the same URL as its untyped counterpart, andpackages/supabase/test/mock_test.dartcovers typed select and typed streams.Linear: SDK-1361