Refactor TypeCast deparser to use AST-driven logic instead of string inspection #234
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Refactor TypeCast deparser to use AST-driven logic
Summary
Refactored the
TypeCastdeparser method to eliminate string-based heuristics (likearg.includes('(')andarg.startsWith('-')) and replace them with AST-driven logic that inspects node types and structure directly.Key Changes
Added 4 helper methods for AST inspection:
isQualifiedName()- Check if names array matches expected path (e.g.,['pg_catalog', 'bpchar'])isBuiltinPgCatalogType()- Check if type is built-in pg_catalog typenormalizeTypeName()- Extract normalized type name from TypeName nodeargumentNeedsCastSyntax()- Determine if argument needsCAST()syntax based on AST node typeRefactored TypeCast method to:
A_Const,ColumnRef,FuncCall) instead of rendered string inspectionival/fvalvalues in A_Const nodesCAST()syntax for negative numbers to avoid SQL precedence issuespg_catalog.bpcharand negative number casts::syntax with parentheses (matching original behavior)Test results: All 657 tests passing (reduced from 43 failures initially)
Technical Details
The original code used string inspection on the rendered argument:
The new code inspects the AST structure directly:
Updates Since Initial Commit
Fixed CI failures by correcting
argumentNeedsCastSyntax()to allow FuncCall nodes to use::syntax. The initial implementation incorrectly returnedtruefor all FuncCall nodes, preventing the existing FuncCall handling code (which wraps them in parentheses) from ever executing. This caused 3 snapshot test failures where function calls were being formatted withCAST()instead of(...)::type.Review & Testing Checklist for Human
ivalandfvalfields. Test with very large negative numbers (int8 range:-9223372036854775808), negative floats, and edge cases like-0.(func1(func2()))::text).CAST()syntax correctly and don't regress.Test Plan
cd packages/deparser && yarn testSELECT (-2147483648)::int4,SELECT (-1.5)::numericSELECT (gen_random_uuid())::text,SELECT (CAST(now() AS text))::dateNotes
String(fval).startsWith('-')which is technically string inspection on the AST literal value (not the rendered SQL). This is a pragmatic compromise for handling float representations.