Skip to content

fix(plpgsql-deparser): preserve ALIAS FOR declarations#312

Merged
pyramation merged 1 commit into
mainfrom
fix/plpgsql-alias-declarations
Jul 22, 2026
Merged

fix(plpgsql-deparser): preserve ALIAS FOR declarations#312
pyramation merged 1 commit into
mainfrom
fix/plpgsql-alias-declarations

Conversation

@pyramation

Copy link
Copy Markdown
Collaborator

Summary

Closes the last PL/pgSQL round-trip gap: ALIAS FOR declarations were dropped on deparse, so bodies referenced undeclared names:

DECLARE arg ALIAS FOR $1;   -- input
BEGIN RETURN arg + 1; END    -- old output: no declaration, `arg` undefined

The parser half already shipped — libpg-query@18.1.2 (which this repo now consumes) serializes aliases on PLpgSQL_function:

"aliases":[{"PLpgSQL_alias":{"name":"arg","varno":0,"lineno":2}}]

This PR is the deparser half (nothing else renders it):

  • new PLpgSQL_alias type ({name, varno, lineno?}) on PLpgSQL_function.aliases
  • deparseDeclareSection emits name ALIAS FOR <datums[varno].refname>; interleaved with variable declarations by source lineno (variables win ties, so an alias of a local variable follows its target's declaration)
  • fixtures 63–65 (positional-param, named-param + local-var interleaving, old/new trigger aliases) + snapshot tests

Note: the DECLARE section now round-trips exactly; a RETURN <alias> body still deparses to the alias's target name (e.g. RETURN buffer / RETURN NEW) because the RETURN carries retvarno pointing at the underlying datum — semantically identical and AST-round-trip-clean, just not textually the alias.

Supersedes #308 (rebuilt fresh on current PG18 main; #308 can be closed).

Local: plpgsql-deparser 109, plpgsql-parser 303, plpgsql-parse 9, parse 68 — all green against the published 18.1.2 parser.

Link to Devin session: https://app.devin.ai/sessions/eeb8deba0c04475091df703c88877302
Requested by: @pyramation

…metadata

libpg-query 18.1.2 serializes PL/pgSQL ALIAS declarations as an aliases
array on PLpgSQL_function ({name, varno, lineno}); previously the alias
name lived only in the compiler namespace and was dropped, so deparsed
bodies referenced undeclared names.

The deparser now renders 'name ALIAS FOR <datums[varno].refname>;',
interleaved with variable declarations by source lineno (variables win
ties) so an alias of a local variable follows its target's declaration.

Fixtures 63-65 cover positional-param, named-param/local-var interleaving,
and OLD/NEW trigger aliases.
@pyramation pyramation self-assigned this Jul 22, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit 792dcf3 into main Jul 22, 2026
9 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.

1 participant