Skip to content

fixes#387

Merged
darold merged 3 commits intodarold:masterfrom
bkircher:fixes
Mar 22, 2026
Merged

fixes#387
darold merged 3 commits intodarold:masterfrom
bkircher:fixes

Conversation

@bkircher
Copy link
Contributor

@bkircher bkircher commented Mar 20, 2026

  • Fix crash on uninitialized variable
    This commit fixes a crash on uninitialized _next_token in CTE/explain path.

    When a closing parenthesis is the last meaningful token in a statement,
    _next_token returns undef. The CTE/explain code path called uc() on it
    unconditionally, triggering a "Use of uninitialized value in uc" warning
    that the $SIG{__WARN__} handler in pg_format promotes to a fatal
    exception.

    Add a defined guard before the uc() call, consistent with the existing patterns here.

    Example SQL that triggers the crash:

    \copy (
      SELECT a.id FROM t
    ) TO STDOUT WITH (FORMAT csv)

    Any query where ')' is the final token while _is_in_with or _is_in_explain is active will hit this path.

  • Preserve inline $$…$$ dollar-quoted strings
    This commit fixes verbatim string handling of inline $$…$$ dollar-quoted strings by treating them as constants.

    Dollar-quoted string literals like $$https://example.com$$ were being tokenized as separate $$ delimiters with the content formatted as SQL; adding spaces, changing keyword case, and breaking the string value.

  • tests: update for dollar-quoted strings
    Dollar-quoted strings are string literals and their contents should be left alone.

This commit fixes a crash on uninitialized _next_token in CTE/explain
path.

When a closing parenthesis is the last meaningful token in a statement,
_next_token returns undef. The CTE/explain code path called `uc()` on it
unconditionally, triggering a "Use of uninitialized value in uc" warning
that the $SIG{__WARN__} handler in pg_format promotes to a fatal
exception.

Add a `defined` guard before the `uc()` call, consistent with the
existing patterns here.

Example SQL that triggers the crash:

    \copy (
      SELECT a.id FROM t
    ) TO STDOUT WITH (FORMAT csv)

Any query where ')' is the final token while _is_in_with or
_is_in_explain is active will hit this path.
This commit fixes verbatim string handling of inline $$…$$ dollar-quoted
strings by treating them as constants.

Dollar-quoted string literals like $$https://example.com$$ were being
tokenized as separate $$ delimiters with the content formatted as SQL;
adding spaces, changing keyword case, and breaking the string value.
Dollar-quoted strings are string literals and their contents should be
left alone.
@bkircher
Copy link
Contributor Author

Tests still pass:

perl t/02_regress.t
1..81
ok 1 - ./pg_format compiles OK
ok 2 - Test file t/test-files/expected/ex0.sql
ok 3 - Test file t/test-files/expected/ex1.sql
ok 4 - Test file t/test-files/expected/ex10.sql
ok 5 - Test file t/test-files/expected/ex11.sql
ok 6 - Test file t/test-files/expected/ex12.sql
ok 7 - Test file t/test-files/expected/ex13.sql
ok 8 - Test file t/test-files/expected/ex14.sql
ok 9 - Test file t/test-files/expected/ex15.sql
ok 10 - Test file t/test-files/expected/ex16.sql
ok 11 - Test file t/test-files/expected/ex17.sql
ok 12 - Test file t/test-files/expected/ex18.sql
ok 13 - Test file t/test-files/expected/ex19.sql
ok 14 - Test file t/test-files/expected/ex2.sql
ok 15 - Test file t/test-files/expected/ex20.sql
ok 16 - Test file t/test-files/expected/ex21.sql
ok 17 - Test file t/test-files/expected/ex22.sql
ok 18 - Test file t/test-files/expected/ex23.sql
ok 19 - Test file t/test-files/expected/ex24.sql
ok 20 - Test file t/test-files/expected/ex25.sql
ok 21 - Test file t/test-files/expected/ex26.sql
ok 22 - Test file t/test-files/expected/ex27.sql
ok 23 - Test file t/test-files/expected/ex28.sql
ok 24 - Test file t/test-files/expected/ex29.sql
ok 25 - Test file t/test-files/expected/ex3.sql
ok 26 - Test file t/test-files/expected/ex30.sql
ok 27 - Test file t/test-files/expected/ex31.sql
ok 28 - Test file t/test-files/expected/ex32.sql
ok 29 - Test file t/test-files/expected/ex33.sql
ok 30 - Test file t/test-files/expected/ex34.sql
ok 31 - Test file t/test-files/expected/ex35.sql
ok 32 - Test file t/test-files/expected/ex36.sql
ok 33 - Test file t/test-files/expected/ex37.sql
ok 34 - Test file t/test-files/expected/ex38.sql
ok 35 - Test file t/test-files/expected/ex39.sql
ok 36 - Test file t/test-files/expected/ex4.sql
ok 37 - Test file t/test-files/expected/ex40.sql
ok 38 - Test file t/test-files/expected/ex41.sql
ok 39 - Test file t/test-files/expected/ex42.sql
ok 40 - Test file t/test-files/expected/ex43.sql
ok 41 - Test file t/test-files/expected/ex44.sql
ok 42 - Test file t/test-files/expected/ex45.sql
ok 43 - Test file t/test-files/expected/ex46.sql
ok 44 - Test file t/test-files/expected/ex47.sql
ok 45 - Test file t/test-files/expected/ex48.sql
ok 46 - Test file t/test-files/expected/ex49.sql
ok 47 - Test file t/test-files/expected/ex5.sql
ok 48 - Test file t/test-files/expected/ex50.sql
ok 49 - Test file t/test-files/expected/ex51.sql
ok 50 - Test file t/test-files/expected/ex52.sql
ok 51 - Test file t/test-files/expected/ex53.sql
ok 52 - Test file t/test-files/expected/ex54.sql
ok 53 - Test file t/test-files/expected/ex55.sql
ok 54 - Test file t/test-files/expected/ex56.sql
ok 55 - Test file t/test-files/expected/ex57.sql
ok 56 - Test file t/test-files/expected/ex58.sql
ok 57 - Test file t/test-files/expected/ex59.sql
ok 58 - Test file t/test-files/expected/ex6.sql
ok 59 - Test file t/test-files/expected/ex60.sql
ok 60 - Test file t/test-files/expected/ex61.sql
ok 61 - Test file t/test-files/expected/ex62.sql
ok 62 - Test file t/test-files/expected/ex63.sql
ok 63 - Test file t/test-files/expected/ex64.sql
ok 64 - Test file t/test-files/expected/ex65.sql
ok 65 - Test file t/test-files/expected/ex66.sql
ok 66 - Test anonymize
ok 67 - Test file t/test-files/expected/ex68.sql
ok 68 - Test file t/test-files/expected/ex69.sql
ok 69 - Test file t/test-files/expected/ex7.sql
ok 70 - Test file t/test-files/expected/ex70.sql
ok 71 - Test file t/test-files/expected/ex71.sql
ok 72 - Test file t/test-files/expected/ex72.sql
ok 73 - Test file t/test-files/expected/ex73.sql
ok 74 - Test file t/test-files/expected/ex74.sql
ok 75 - Test file t/test-files/expected/ex75.sql
ok 76 - Test file t/test-files/expected/ex76.sql
ok 77 - Test file t/test-files/expected/ex77.sql
ok 78 - Test file t/test-files/expected/ex78.sql
ok 79 - Test file t/test-files/expected/ex79.sql
ok 80 - Test file t/test-files/expected/ex8.sql
ok 81 - Test file t/test-files/expected/ex9.sql

@bkircher bkircher marked this pull request as ready for review March 20, 2026 09:55
@darold darold merged commit cd7bc94 into darold:master Mar 22, 2026
4 checks passed
@darold
Copy link
Owner

darold commented Mar 22, 2026

Thanks Ben!

@darold
Copy link
Owner

darold commented Mar 22, 2026

@bkircher I have patched your change on dollar quoted string, see commit bf29ea6 it should nt be applied to function declaration like:

CREATE OR REPLACE FUNCTION rngfuncr(in f1 int, out f2 int, out text)
AS $$select $1-1, $1::text || 'z'$$ LANGUAGE sql;

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.

2 participants