You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #623 (which added the JSONPath selector-with-constraint to the Drizzle v3 integration).
Problem
The Supabase v3 adapter has no encrypted-JSON querying at all — not even the #621 containment (that lives only in Drizzle). searchableJson / query_jsonb / ste_vec / selector have zero references in packages/stack-supabase/src/. Encrypted eql_v3_json columns round-trip through select/insert, but they are non-queryable on this surface, and the typed key sets actively exclude them (a JSON column resolves to never in QueryTypesForColumn).
The hard part: PostgREST can't cast a filter value
The Drizzle path works because it emits raw SQL with the casts the overloads require (::eql_v3.query_jsonb for containment, ::public.eql_v3_jsonb_entry for the selector comparison). PostgREST has no syntax to cast a filter value, and an uncast literal is ambiguous across the @> / comparison overloads (42725 "operator is not unique"). This is the same wall the scalar v3 filters hit — they escape it by sending the full storage envelope to a no-cast overload, but a JSON query needle can't be a full storage envelope.
Required investigation (do this first)
A live-PostgREST probe to find a filter form that reaches an overload needing no value cast — mirroring how ordering already works (order=col->op.asc needs no operand/cast; see query-builder-v3.ts:282-320). If no such form exists for the encrypted-JSON overloads, this needs an EQL-bundle change (a no-cast-friendly overload) — coordinate with the EQL project.
Plumbing (once the wire form is settled)
Core: add a searchableJson arm to QueryTypesForColumn (packages/stack/src/eql/v3/columns.ts:770) so JSON columns stop resolving to never.
packages/stack-supabase/src/types.ts: a V3SearchableJsonKeys key set (sibling to V3EncryptedFreeTextKeys), remove JSON columns from NonQueryableV3Keys erasure, add a FilterOp member + builder method.
packages/stack-supabase/src/query-builder-v3.ts: widen V3ColumnLike.getQueryCapabilities, add searchableJson arms to queryTypeForRawOp/queryTypeForOrOp/assertTermQueryable, and a new applier seam beside applyContainsFilter.
Reference impl: packages/stack-drizzle/src/v3/operators.ts (containment containsJsonOp; selector selectorCompare) and sql-dialect.ts.
Live tests in packages/stack-supabase/integration/wire.integration.test.ts (add an eql_v3_json fixture column).
Context
Split out of #623 during the Stack 1.0 push: the Drizzle selector was clean and unblocked, but the Supabase path needs genuine PostgREST design work that shouldn't gate the Drizzle capability for launch.
Follow-up to #623 (which added the JSONPath selector-with-constraint to the Drizzle v3 integration).
Problem
The Supabase v3 adapter has no encrypted-JSON querying at all — not even the #621 containment (that lives only in Drizzle).
searchableJson/query_jsonb/ste_vec/selectorhave zero references inpackages/stack-supabase/src/. Encryptedeql_v3_jsoncolumns round-trip through select/insert, but they are non-queryable on this surface, and the typed key sets actively exclude them (a JSON column resolves toneverinQueryTypesForColumn).So Supabase needs BOTH:
@>), the Drizzle feat(stack): EQL v3 JSON support — types.Json + containment #621 equivalent.col->'path' <op> value), the EQL v3 JSON: implement JSONPath selector-with-constraint querying (->, ->>) #623 equivalent.The hard part: PostgREST can't cast a filter value
The Drizzle path works because it emits raw SQL with the casts the overloads require (
::eql_v3.query_jsonbfor containment,::public.eql_v3_jsonb_entryfor the selector comparison). PostgREST has no syntax to cast a filter value, and an uncast literal is ambiguous across the@>/ comparison overloads (42725"operator is not unique"). This is the same wall the scalar v3 filters hit — they escape it by sending the full storage envelope to a no-cast overload, but a JSON query needle can't be a full storage envelope.Required investigation (do this first)
A live-PostgREST probe to find a filter form that reaches an overload needing no value cast — mirroring how ordering already works (
order=col->op.ascneeds no operand/cast; seequery-builder-v3.ts:282-320). If no such form exists for the encrypted-JSON overloads, this needs an EQL-bundle change (a no-cast-friendly overload) — coordinate with the EQL project.Plumbing (once the wire form is settled)
searchableJsonarm toQueryTypesForColumn(packages/stack/src/eql/v3/columns.ts:770) so JSON columns stop resolving tonever.packages/stack-supabase/src/types.ts: aV3SearchableJsonKeyskey set (sibling toV3EncryptedFreeTextKeys), remove JSON columns fromNonQueryableV3Keyserasure, add aFilterOpmember + builder method.packages/stack-supabase/src/query-builder-v3.ts: widenV3ColumnLike.getQueryCapabilities, addsearchableJsonarms toqueryTypeForRawOp/queryTypeForOrOp/assertTermQueryable, and a new applier seam besideapplyContainsFilter.packages/stack-drizzle/src/v3/operators.ts(containmentcontainsJsonOp; selectorselectorCompare) andsql-dialect.ts.packages/stack-supabase/integration/wire.integration.test.ts(add aneql_v3_jsonfixture column).Context
Split out of #623 during the Stack 1.0 push: the Drizzle selector was clean and unblocked, but the Supabase path needs genuine PostgREST design work that shouldn't gate the Drizzle capability for launch.