Skip to content

Commit d609e87

Browse files
FFX3claude
andauthored
fix: strip quotes from type names in view dependency detection (#337)
* fix: strip quotes from type names in view dependency detection 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> * test: add unit tests for extractBaseTypeName Add tests for the extractBaseTypeName function to verify correct handling of quoted identifiers in type expressions. Tests cover: - Simple types - SETOF prefix with schema-qualified types - Quoted type names (e.g., SETOF public."ViewName") - Quoted schema and type names - Array notation - Combined cases (SETOF + quoted + array) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 53df33d commit d609e87

2 files changed

Lines changed: 64 additions & 1 deletion

File tree

internal/diff/diff.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1938,7 +1938,7 @@ func functionReferencesNewView(fn *ir.Function, newViews map[string]struct{}) bo
19381938
}
19391939

19401940
// extractBaseTypeName extracts the base type name from a type expression,
1941-
// stripping SETOF prefix and array notation.
1941+
// stripping SETOF prefix, array notation, and double quotes from identifiers.
19421942
func extractBaseTypeName(typeExpr string) string {
19431943
t := strings.TrimSpace(typeExpr)
19441944
// Strip SETOF prefix (case-insensitive)
@@ -1949,6 +1949,8 @@ func extractBaseTypeName(typeExpr string) string {
19491949
for len(t) > 2 && t[len(t)-2:] == "[]" {
19501950
t = t[:len(t)-2]
19511951
}
1952+
// Strip double quotes from identifiers (e.g., public."ViewName" -> public.ViewName)
1953+
t = strings.ReplaceAll(t, "\"", "")
19521954
return t
19531955
}
19541956

internal/diff/type_extract_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package diff
2+
3+
import "testing"
4+
5+
func TestExtractBaseTypeName(t *testing.T) {
6+
tests := []struct {
7+
name string
8+
typeExpr string
9+
want string
10+
}{
11+
{
12+
name: "simple type",
13+
typeExpr: "integer",
14+
want: "integer",
15+
},
16+
{
17+
name: "SETOF simple type",
18+
typeExpr: "SETOF actor",
19+
want: "actor",
20+
},
21+
{
22+
name: "SETOF with schema",
23+
typeExpr: "SETOF public.actor",
24+
want: "public.actor",
25+
},
26+
{
27+
name: "SETOF with quoted type name",
28+
typeExpr: `SETOF public."ViewName"`,
29+
want: "public.ViewName",
30+
},
31+
{
32+
name: "SETOF with quoted schema and type",
33+
typeExpr: `SETOF "Schema"."ViewName"`,
34+
want: "Schema.ViewName",
35+
},
36+
{
37+
name: "quoted type only",
38+
typeExpr: `"MyType"`,
39+
want: "MyType",
40+
},
41+
{
42+
name: "array type",
43+
typeExpr: "integer[]",
44+
want: "integer",
45+
},
46+
{
47+
name: "SETOF quoted type with array",
48+
typeExpr: `SETOF public."ViewName"[]`,
49+
want: "public.ViewName",
50+
},
51+
}
52+
53+
for _, tt := range tests {
54+
t.Run(tt.name, func(t *testing.T) {
55+
got := extractBaseTypeName(tt.typeExpr)
56+
if got != tt.want {
57+
t.Errorf("extractBaseTypeName(%q) = %q, want %q", tt.typeExpr, got, tt.want)
58+
}
59+
})
60+
}
61+
}

0 commit comments

Comments
 (0)