Skip to content

fix: create SQL functions after the later-batch functions they call (#596) - #616

Merged
tianzhou merged 3 commits into
mainfrom
fix/sql-function-call-ordering
Sep 20, 2026
Merged

tianzhou merged 3 commits into
mainfrom
fix/sql-function-call-ordering

Conversation

@tianzhou

@tianzhou tianzhou commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #615 (merged), found while applying the schema attached to #596. Since #615 the schema plans, but pgschema apply then failed:

ERROR: function apni_ordered_nom_synonymy(bigint) does not exist (SQLSTATE 42883)

New functions are emitted in several batches (before function-dependent tables, after them, after the last table batch, after views, after aggregates). topologicallySortFunctions orders functions only within a batch. A LANGUAGE sql function that touches no new table itself but calls a function deferred to a later batch stayed in the first batch, so it was created before its callee — and SQL-language bodies are validated at creation time.

Fix: the transitive "a caller of a held-back function waits too" closure that splitFunctionsCallingAggregates already had is extracted into holdBackCallers and also applied to the table batches and the view batch. Only SQL-language functions move; plpgsql resolves calls at run time, and moving those could push trigger functions past their triggers.

Fixes #596

Test plan

  • Folded into testdata/diff/dependency/issue_530_function_table_function_chain: first_is_flagged() references no table but calls x_is_flagged, which is created after table x. Fails before the fix at apply, passes after.
  • Ran dependency/, create_function/, create_aggregate/ for both TestDiffFromFiles and TestPlanAndApply.
  • Rebased on main (includes fix: resolve managed-schema qualifiers in inlined SQL function bodies (#596) #615): the reporter's 9.3k-line schema applies via pgschema apply and re-plans to No changes detected.
PGSCHEMA_TEST_FILTER="dependency/issue_530" go test -v ./cmd -run TestPlanAndApply
PGSCHEMA_TEST_FILTER="dependency/" go test -v ./internal/diff -run TestDiffFromFiles

🤖 Generated with Claude Code

Copilot AI balanced review requested due to automatic review settings September 20, 2026 04:31
@greptile-apps

greptile-apps Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 2/5

The PR is not safe to merge because several realistic dependency chains can still create SQL functions or function-dependent tables before their required routines exist.

Findings

  1. P1 Pairwise passes miss callers ▶
  2. P1 Functions move past dependent tables ▶
  3. P1 Recreated-view callers remain early ▶

Summary

This PR extracts transitive SQL-function caller holdback logic and applies it across table and view creation batches so callers follow functions whose creation is deferred.

  • Adds caller propagation between the three table-relative function batches.
  • Adds caller propagation for functions dependent on newly created views.
  • Extends the dependency fixture with a SQL caller of a table-dependent function.
  • The current partition sequence still permits callers and dependent tables to be emitted before their prerequisites.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Independent functions] --> B[Tables depending on functions]
    B --> C[Table-dependent functions]
    C --> D[Final table batch]
    D --> E[Functions after all tables]
    E --> F[Views and view-dependent functions]

    H[Pairwise caller holdback] -. can move a prerequisite past B .-> C
    I[Later partition changes] -. not rechecked .-> E
    J[Recreated-view functions] -. extracted after closure .-> G[Modify phase]
Loading

Reviews (1) · Last reviewed commit: "fix: create SQL functions after the late..."

Comment thread internal/diff/diff.go Outdated
Comment thread internal/diff/diff.go Outdated
Comment thread internal/diff/diff.go

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Cross-batch scheduling and imprecise call detection can still emit functions after objects that require them.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 3 High severity

Open (3)
What changed in this PR

Improves PostgreSQL function creation ordering when SQL functions call functions deferred to later dependency batches.

Changes:

  • Extracts transitive caller deferral into holdBackCallers.
  • Applies caller deferral across table and view batches.
  • Extends dependency regression fixtures and expected plans.
File Description
testdata/​diff/​dependency/​issue_530_function_table_function_chain/​plan.txt Updates human-readable expected plan.
testdata/​diff/​dependency/​issue_530_function_table_function_chain/​plan.sql Updates expected plan SQL.
testdata/​diff/​dependency/​issue_530_function_table_function_chain/​plan.json Updates expected JSON plan.
testdata/​diff/​dependency/​issue_530_function_table_function_chain/​new.sql Adds an indirect SQL-function dependency case.
testdata/​diff/​dependency/​issue_530_function_table_function_chain/​diff.sql Updates expected migration SQL.
internal/​diff/​diff.go Adds transitive caller deferral across creation batches.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/diff/diff.go
Comment thread internal/diff/diff.go Outdated
Comment thread internal/diff/diff.go
…596)

New functions are emitted in several batches (before/after function-dependent
tables, after views, after aggregates), and topologicallySortFunctions only
orders within a batch. A LANGUAGE sql function that touches no new table but
calls a function deferred to a later batch was created first, and apply failed
with `function ... does not exist` because SQL bodies are validated at creation.

Generalize the transitive hold-back already used for aggregate callers into
holdBackCallers and apply it to the table and view batches.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@tianzhou
tianzhou force-pushed the fix/sql-function-call-ordering branch from e57436c to ccc263c Compare September 20, 2026 06:16
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The newly added view-batch scheduling path still lacks regression coverage.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
Resolved since last review (3)

Comment thread internal/diff/diff.go
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The focused ordering fix has targeted unit and integration coverage with no unresolved findings.

Review effort: Balanced
Findings: None

Resolved since last review (1)

@tianzhou
tianzhou merged commit f04028c into main Sep 20, 2026
2 checks passed
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.

table not found

2 participants