Skip to content

Commit 463a07a

Browse files
authored
Implement ALTER TYPE RENAME VALUE / ADD VALUE (#433)
* postgresql: Implement ALTER TYPE RENAME/ADD VALUE * catalog: Implement ALTER TYPE RENAME/ADD VALUE This is a backport of the implementation from sql/catalog.
1 parent 0f922ee commit 463a07a

File tree

7 files changed

+290
-2
lines changed

7 files changed

+290
-2
lines changed

internal/catalog/build.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,56 @@ func Update(c *pg.Catalog, stmt nodes.Node) error {
9999

100100
switch n := raw.Stmt.(type) {
101101

102+
case nodes.AlterEnumStmt:
103+
fqn, err := ParseList(n.TypeName)
104+
if err != nil {
105+
return err
106+
}
107+
schema, exists := c.Schemas[fqn.Schema]
108+
if !exists {
109+
return wrap(pg.ErrorSchemaDoesNotExist(fqn.Schema), raw.StmtLocation)
110+
}
111+
typ, exists := schema.Types[fqn.Rel]
112+
if !exists {
113+
return wrap(pg.ErrorRelationDoesNotExist(fqn.Rel), raw.StmtLocation)
114+
}
115+
enum, ok := typ.(pg.Enum)
116+
if !ok {
117+
return wrap(pg.ErrorRelationDoesNotExist(fqn.Rel), raw.StmtLocation)
118+
}
119+
oldIndex := -1
120+
newIndex := -1
121+
for i, val := range enum.Vals {
122+
if n.OldVal != nil && val == *n.OldVal {
123+
oldIndex = i
124+
}
125+
if n.NewVal != nil && val == *n.NewVal {
126+
newIndex = i
127+
}
128+
}
129+
if n.OldVal != nil {
130+
// RENAME TYPE
131+
if oldIndex < 0 {
132+
return fmt.Errorf("type %s does not have value %s", fqn.Rel, *n.OldVal)
133+
}
134+
if newIndex >= 0 {
135+
return fmt.Errorf("type %s already has value %s", fqn.Rel, *n.NewVal)
136+
}
137+
enum.Vals[oldIndex] = *n.NewVal
138+
schema.Types[fqn.Rel] = enum
139+
} else {
140+
// ADD VALUE
141+
if newIndex >= 0 {
142+
if !n.SkipIfNewValExists {
143+
return fmt.Errorf("type %s already has value %s", fqn.Rel, *n.NewVal)
144+
} else {
145+
return nil
146+
}
147+
}
148+
enum.Vals = append(enum.Vals, *n.NewVal)
149+
schema.Types[fqn.Rel] = enum
150+
}
151+
102152
case nodes.AlterObjectSchemaStmt:
103153
switch n.ObjectType {
104154

internal/catalog/build_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,43 @@ func TestUpdate(t *testing.T) {
4545
},
4646
},
4747
},
48+
{
49+
`
50+
CREATE TYPE status AS ENUM ('open', 'closed');
51+
ALTER TYPE status RENAME VALUE 'closed' TO 'shut';
52+
`,
53+
pg.Catalog{
54+
Schemas: map[string]pg.Schema{
55+
"public": {
56+
Types: map[string]pg.Type{
57+
"status": pg.Enum{
58+
Name: "status",
59+
Vals: []string{"open", "shut"},
60+
},
61+
},
62+
},
63+
},
64+
},
65+
},
66+
{
67+
`
68+
CREATE TYPE status AS ENUM ('open', 'closed');
69+
ALTER TYPE status ADD VALUE 'unknown';
70+
ALTER TYPE status ADD VALUE IF NOT EXISTS 'unknown';
71+
`,
72+
pg.Catalog{
73+
Schemas: map[string]pg.Schema{
74+
"public": {
75+
Types: map[string]pg.Type{
76+
"status": pg.Enum{
77+
Name: "status",
78+
Vals: []string{"open", "closed", "unknown"},
79+
},
80+
},
81+
},
82+
},
83+
},
84+
},
4885
{
4986
"CREATE TABLE venues ();",
5087
pg.Catalog{
@@ -240,6 +277,27 @@ func TestUpdate(t *testing.T) {
240277
},
241278
},
242279
},
280+
/*
281+
{
282+
`
283+
CREATE TYPE status AS ENUM ('open', 'closed');
284+
ALTER TYPE status RENAME VALUE 'closed' TO 'shut';
285+
`,
286+
pg.Catalog{
287+
Schemas: map[string]pg.Schema{
288+
"public": {
289+
Types: map[string]pg.Type{
290+
"status": pg.Enum{
291+
Name: "status",
292+
Vals: []string{"open", "shut"},
293+
},
294+
},
295+
Tables: map[string]pg.Table{},
296+
},
297+
},
298+
},
299+
},
300+
*/
243301
{
244302
`
245303
CREATE TABLE venues ();

0 commit comments

Comments
 (0)