Skip to content

Add support for PostgreSQL procedures (CALL-based mutations) - #3124

Open
dargmuesli wants to merge 8 commits into
graphile:mainfrom
dargmuesli:feat/pg-procedures
Open

Add support for PostgreSQL procedures (CALL-based mutations)#3124
dargmuesli wants to merge 8 commits into
graphile:mainfrom
dargmuesli:feat/pg-procedures

Conversation

@dargmuesli

@dargmuesli dargmuesli commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Resolves #1309.

Adds support for PostgreSQL PROCEDUREs (introduced in PG11). Previously a procedure either didn't appear in the schema or got built into a GraphQL field that crashed at query time, since Postgres procedures can only be invoked with call proc(...), never embedded in a select like a function.

  • @dataplan/pg: new PgCallStep/pgCall() step that builds and executes a call statement directly, including the positional-argument handling procedures require (every parameter, including OUT-only ones, needs a value) and raw-text decoding for the output columns (which can't be wrapped in ::text casts the way a select list can).
  • graphile-build-pg: PgProceduresPlugin detects prokind = 'p' and builds a CALL-backed resource; procedures are always mutation fields, since they can never appear in a query, computed column, or connection. PgCustomTypeFieldPlugin's clientMutationId wiring is extended to recognize PgCallStep results alongside PgSelectStep ones.
  • Test coverage: a new procedures schema (PG11+) covering no-output, single-output, multiple-output, and INOUT procedures, plus a mutation test exercising each including clientMutationId.
  • Docs: procedures.md now documents the feature and its limitations instead of saying it's unsupported.

Known limitation: a single-output procedure's result is a nested object ({ result { doubled } }) rather than flattened to a bare scalar the way single-output functions are, since Postgres reports record as a procedure's return type even with just one OUT parameter.

@changeset-bot

changeset-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c4d1b55

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@dataplan/pg Minor
graphile-build-pg Minor
postgraphile Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@benjie

benjie commented Aug 5, 2026

Copy link
Copy Markdown
Member

since Postgres reports record as a procedure's return type even with just one OUT parameter

I think this might be the case for regular functions too, if so we have handling for it already. I might be wrong though.

@benjie

benjie commented Aug 5, 2026

Copy link
Copy Markdown
Member

Only glancing at this because I'm in the middle of some other work, so forgive brevity.

Seems CALL doesn't allow casting, selections, etc; and the encoding is going to differ according to the client used (e.g. pg might encode it differently to postgres). I think if you need to use CALL you're probably better off using sideEffectWithPgClient(...) to load the record, and then for records turn that into something we can use via pgSelectFromRecords / pgSelectSingleFromRecord... Though that is a little in-efficient (feeding the data back into the DB).

@dargmuesli

dargmuesli commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the quick feedback! I evaluated using PROCEDUREs in my app a bit more and came to the conclusion that they are of little use for me and I think most other postgraphile projects will come to a similar conclusion. Let me know if you think supporting PROCEDUREs is even in scope for postgraphile. Not saying it shouldn't be but it's definitely an edge case / advanced feature. If you think supporting it makes sense, I'll take care of your feedback above!

@benjie

benjie commented Aug 5, 2026

Copy link
Copy Markdown
Member

I'm somewhat indifferent to it until someone has a really pressing and convincing need for it. Functions are pretty powerful and the integrate well and efficiently into the system 🤷‍♂️

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.

Feature request: procedure (as well as function) support

2 participants