Skip to content

Conversation

@pyramation
Copy link
Collaborator

@pyramation pyramation commented Nov 23, 2025

Fix #217: Wrap FuncCall arguments in parentheses when using :: cast syntax

Summary

Fixes a bug where double type casts with the :: operator were being deparsed incorrectly due to operator precedence issues. The problem occurred when a FuncCall (like AT TIME ZONE) was cast using the :: shorthand syntax, causing the cast to bind to the wrong operand.

Example of the bug:

  • Input SQL: SELECT CAST(t.date AT TIME ZONE 'America/New_York' AS text)::date FROM tbl t
  • Incorrect output: SELECT CAST(t.date AT TIME ZONE 'America/New_York'::text AS date) FROM tbl AS t
  • The ::text was binding to 'America/New_York' instead of the entire CAST(...) expression

The fix:
When using the :: cast shorthand syntax with a FuncCall argument, wrap the FuncCall in parentheses to ensure correct operator precedence: (t.date AT TIME ZONE 'America/New_York')::text

Review & Testing Checklist for Human

⚠️ IMPORTANT: This PR contains extensive auto-formatting changes (import reordering, indentation) that are unrelated to the actual fix. The functional change is small but buried in the diff.

  • Review the core logic change in packages/deparser/src/deparser.ts lines 2256-2268 (the TypeCast function). The key change is wrapping FuncCall arguments in parentheses when using :: syntax.
  • Verify the snapshot change in pg-catalog.test.ts.snap is correct: function calls like public.gen_random_uuid()::text now become (public.gen_random_uuid())::text. This is intentional to prevent precedence issues.
  • Test the original issue: Verify that SELECT CAST(t.date AT TIME ZONE 'America/New_York' AS text)::date FROM tbl t now deparses correctly and can be re-parsed without AST changes.
  • Spot check other type casts: Verify simple casts like '123'::int still work correctly (they should, as the fix only affects FuncCall arguments).

Test Plan

  1. Run the test suite: cd packages/deparser && yarn test (all 654 tests should pass)
  2. Test the specific issue: Parse and deparse the SQL from issue Double CAST Error #217 and verify it round-trips correctly
  3. Test edge cases: Try other double casts and function call casts to ensure no regressions

Notes

  • All 654 deparser tests pass
  • Added test fixture for issue Double CAST Error #217 in misc-issues.test.ts
  • The fix refactored an empty if block to pass lint checks
  • Warning: The diff includes many unrelated formatting changes that make review difficult. Focus on the TypeCast function changes.

Devin Session: https://app.devin.ai/sessions/111a29019c274f83a61a873f35081622
Requested by: Dan Lynch (@pyramation)

pyramation and others added 3 commits November 22, 2025 16:08
…cast syntax

- Fixes operator precedence issues with double casts like CAST(...AS text)::date
- Wraps FuncCall arguments (e.g., AT TIME ZONE expressions) in parentheses
- Prevents :: operator from binding to wrong operand
- Refactored empty if block to pass lint checks
- Updated pg-catalog snapshot to reflect correct parenthesization

Co-Authored-By: Dan Lynch <[email protected]>
@devin-ai-integration
Copy link
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 and CI monitoring

@devin-ai-integration
Copy link
Contributor

This PR has been superseded by #227 which contains the same fix but without the accidental formatting changes.

PR #227 has a minimal diff with only 2 files changed (8 insertions, 3 deletions) making it much easier to review. The functional change is identical - wrapping FuncCall arguments in parentheses when using the :: cast syntax to fix operator precedence issues.

Closing this PR in favor of the cleaner version.

@pyramation pyramation closed this Nov 23, 2025
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.

Double CAST Error

2 participants