Skip to content

fix(typescript): make grouped function sort fully deterministic#1071

Open
selenaalpha77-sketch wants to merge 1 commit intosupabase:masterfrom
selenaalpha77-sketch:fix/deterministic-function-sort-1008
Open

fix(typescript): make grouped function sort fully deterministic#1071
selenaalpha77-sketch wants to merge 1 commit intosupabase:masterfrom
selenaalpha77-sketch:fix/deterministic-function-sort-1008

Conversation

@selenaalpha77-sketch
Copy link
Copy Markdown

Problem

When generating TypeScript types, functions with the same name are grouped together and sorted by argument_types and return_type to produce stable output. However, if two overloaded functions have identical argument_types and return_type strings (for example, embedded join functions B→A, C→A, D→A that all share the same return table), the sort order is non-deterministic and can change across supabase db reset / dump / restore cycles.

This causes SetofOptions in the generated types to be unstable — the same database schema can generate different TypeScript output depending on the internal PostgreSQL OID ordering.

Closes #1008

Fix

Add a.fn.id - b.fn.id as a final tiebreaker in the sort comparator. Function id is the PostgreSQL OID (a stable integer per function), so this guarantees a fully deterministic ordering regardless of how functions are sequenced in the catalog after a dump/restore.

Changes

  • src/server/templates/typescript.ts: Added || a.fn.id - b.fn.id as tiebreaker in the grouped function sort

Testing

To reproduce the original bug:

  1. Create functions fn_b_to_a(b), fn_c_to_a(c), fn_d_to_a(d) — all returning setof a
  2. Run typegen, note the order of SetofOptions in the output
  3. supabase db reset → restore → typegen again
  4. Order is now stable with this fix

🤖 Generated with Claude Code

When multiple overloaded functions share the same name, argument_types,
and return_type, the sort order was not guaranteed to be stable across
different database states or dump/restore cycles. Add function id as a
final tiebreaker so that SetofOptions generation is always deterministic.

Fixes supabase#1008
Copy link
Copy Markdown
Member

@avallete avallete left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to rely over the id as it'll have the same issue, depending on the order this get inserted into the database the oid will change, causing unstable results.

Maybe instead we could rely over the whole definition text as the tiebreaker ? That way, function with the same name, same arguments, same return type AND exact same body definition will always be sorted the same way. Regardless of their insertion order in the database ?

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.

TS schema gen not deterministic in SetofOptions

2 participants