fix: strip quotes from type names in view dependency detection#337
fix: strip quotes from type names in view dependency detection#337FFX3 wants to merge 1 commit intopgplex:mainfrom
Conversation
When a function returns a quoted type like SETOF public."ViewName", the extractBaseTypeName function was not stripping the double quotes. This caused the lookup in functionReferencesNewView to fail because the view lookup map stores unquoted names (e.g., public.viewname). As a result, functions with quoted return types were not detected as having view dependencies, causing them to be created before the views they depend on, leading to "type does not exist" errors. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Greptile SummaryThis PR fixes a bug in Key changes:
Notes:
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Diff as diff.go (orderDDLStatements)
participant FRV as functionReferencesNewView
participant EBT as extractBaseTypeName
participant TML as typeMatchesLookup
participant VL as newViewLookup (map)
Diff->>FRV: fn, newViewLookup
FRV->>EBT: fn.ReturnType (e.g. SETOF public."ViewName")
EBT-->>EBT: strip SETOF → public."ViewName"
EBT-->>EBT: strip [] → public."ViewName"
EBT-->>EBT: strip quotes → public.ViewName [NEW]
EBT-->>FRV: "public.ViewName"
FRV->>TML: typeName="public.ViewName", schema, newViewLookup
TML-->>TML: ToLower → "public.viewname"
TML->>VL: lookup["public.viewname"]
VL-->>TML: found ✓
TML-->>FRV: true
FRV-->>Diff: true → function depends on view, order accordingly
Last reviewed commit: b1f3b10 |
| t = t[:len(t)-2] | ||
| } | ||
| // Strip double quotes from identifiers (e.g., public."ViewName" -> public.ViewName) | ||
| t = strings.ReplaceAll(t, "\"", "") |
There was a problem hiding this comment.
No tests added for the new quoted-identifier behavior
The fix is correct, but there are no unit tests in the diff covering the new quoted-identifier stripping logic. Without tests, future refactors could silently regress this case. Consider adding a test for extractBaseTypeName (or an integration-style test for functionReferencesNewView) that covers at minimum:
SETOF public."ViewName"→public.ViewName"Schema"."View"→Schema.View"MyType"[]→MyTypepublic.unquoted→public.unquoted(no-op, regression guard)
Example:
func TestExtractBaseTypeName_QuotedIdentifiers(t *testing.T) {
cases := []struct {
input, want string
}{
{`SETOF public."ViewName"`, `public.ViewName`},
{`"Schema"."View"`, `Schema.View`},
{`"MyType"[]`, `MyType`},
{`public.unquoted`, `public.unquoted`},
}
for _, tc := range cases {
got := extractBaseTypeName(tc.input)
if got != tc.want {
t.Errorf("extractBaseTypeName(%q) = %q, want %q", tc.input, got, tc.want)
}
}
}| t = t[:len(t)-2] | ||
| } | ||
| // Strip double quotes from identifiers (e.g., public."ViewName" -> public.ViewName) | ||
| t = strings.ReplaceAll(t, "\"", "") |
There was a problem hiding this comment.
Quote-stripping happens before case-folding, but after array stripping — works correctly, but edge case with dot-containing quoted schema names
The approach of strings.ReplaceAll(t, "\"", "") correctly handles the primary cases (public."ViewName" → public.ViewName). However, it will silently mangle a (rare but valid) PostgreSQL identifier where the schema name itself is quoted and contains a dot — e.g., "my.schema"."view" would become my.schema.view, which typeMatchesLookup would treat as schema my + name schema.view instead of schema my.schema + name view.
In practice, schema names with dots are extremely uncommon and buildSchemaNameLookup would store the view under my.schema + view, so the lookup key would be my.schema.view — which happens to match the mangled string by coincidence in this case. However if the lookup was keyed differently this could fail.
This is a very low-probability edge case, but it's worth being aware of. The simpler alternative — stripping only quotes that wrap a single token (e.g., via a small regex like strings.Trim per identifier segment) — would be more precise, but for now the current approach covers all realistic PostgreSQL type expressions.
No code change required unless dot-containing schema names are a supported use case.
tianzhou
left a comment
There was a problem hiding this comment.
Thanks for the contribution. please add an unit test
|
I'll take a look at adding the tests |
When a function returns a quoted type like SETOF public."ViewName", the extractBaseTypeName function was not stripping the double quotes. This caused the lookup in functionReferencesNewView to fail because the view lookup map stores unquoted names (e.g., public.viewname).
As a result, functions with quoted return types were not detected as having view dependencies, causing them to be created before the views they depend on, leading to "type does not exist" errors.