Skip to content

Commit f3eda22

Browse files
committed
feat[engine]: schema diff (#329)
1 parent e509641 commit f3eda22

File tree

3 files changed

+172
-0
lines changed

3 files changed

+172
-0
lines changed

engine/cmd/pgquery/main.go

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
pg_query "github.com/pganalyze/pg_query_go/v2"
8+
)
9+
10+
const idxExample = `
11+
CREATE UNIQUE INDEX title_idx ON films (title);
12+
13+
ALTER TABLE pgbench_accounts
14+
ADD COLUMN test integer NOT NULL DEFAULT 0;
15+
`
16+
17+
var stmts []*pg_query.RawStmt
18+
19+
func main() {
20+
scanTree, err := pg_query.ParseToJSON(idxExample)
21+
if err != nil {
22+
log.Fatal(err)
23+
}
24+
25+
fmt.Printf("JSON: %s\n", scanTree)
26+
27+
idxTree, err := pg_query.Parse(idxExample)
28+
if err != nil {
29+
log.Fatal(err)
30+
}
31+
32+
fmt.Printf("Original query:\n%v\n\n", idxExample)
33+
fmt.Printf("Parse Tree:\n%#v\n\n", idxTree)
34+
35+
stmts = idxTree.GetStmts()
36+
37+
processStmts(stmts)
38+
39+
idxTree.Stmts = stmts
40+
41+
fmt.Printf("Parse Tree after processing:\n%#v\n\n", idxTree.GetStmts()[1].Stmt.Node)
42+
43+
resIdxStr, err := pg_query.Deparse(idxTree)
44+
if err != nil {
45+
log.Fatal(err)
46+
}
47+
48+
fmt.Printf("Optimized query:\n%v\n", resIdxStr)
49+
// CREATE UNIQUE INDEX CONCURRENTLY title_idx ON films USING btree (title);
50+
// ALTER TABLE pgbench_accounts ADD COLUMN test int;
51+
// ALTER TABLE pgbench_accounts ALTER COLUMN test SET DEFAULT 0;
52+
}
53+
54+
func processStmts(stmts []*pg_query.RawStmt) {
55+
for _, stmt := range stmts {
56+
detectNodeType(stmt.Stmt)
57+
}
58+
}
59+
60+
func detectNodeType(node *pg_query.Node) {
61+
switch stmt := node.Node.(type) {
62+
case *pg_query.Node_IndexStmt:
63+
IndexStmt(stmt)
64+
65+
case *pg_query.Node_AlterTableStmt:
66+
fmt.Println("Alter Type")
67+
AlterStmt(stmt)
68+
69+
case *pg_query.Node_SelectStmt:
70+
fmt.Println("Select Type")
71+
72+
}
73+
}
74+
75+
func IndexStmt(stmt *pg_query.Node_IndexStmt) {
76+
stmt.IndexStmt.Concurrent = true
77+
}
78+
79+
func AlterStmt(stmt *pg_query.Node_AlterTableStmt) {
80+
initialCommands := stmt.AlterTableStmt.GetCmds()
81+
82+
commands := []*pg_query.Node{}
83+
for _, cmd := range initialCommands {
84+
switch v := cmd.Node.(type) {
85+
case *pg_query.Node_AlterTableCmd:
86+
87+
fmt.Printf("%#v\n", v)
88+
fmt.Printf("%#v\n", v.AlterTableCmd.Def.Node)
89+
fmt.Println(v.AlterTableCmd.Subtype.Enum())
90+
91+
switch v.AlterTableCmd.Subtype {
92+
case pg_query.AlterTableType_AT_AddColumn:
93+
def := v.AlterTableCmd.Def.GetColumnDef()
94+
95+
constraints := def.GetConstraints()
96+
constraintsMap := make(map[pg_query.ConstrType]int)
97+
98+
for i, constr := range constraints {
99+
constraintsMap[constr.GetConstraint().Contype] = i
100+
}
101+
102+
if index, ok := constraintsMap[pg_query.ConstrType_CONSTR_DEFAULT]; ok {
103+
def.Constraints = make([]*pg_query.Node, 0)
104+
cmd.Node = v
105+
commands = append(commands, cmd)
106+
107+
/* newCmd := &pg_query.Node{
108+
Node: &pg_query.Node_AlterTableCmd{
109+
AlterTableCmd: &pg_query.AlterTableCmd{
110+
Subtype: pg_query.AlterTableType_AT_ColumnDefault,
111+
Name: "",
112+
Num: v.AlterTableCmd.GetNum(),
113+
Newowner: v.AlterTableCmd.GetNewowner(),
114+
Def: pg_query.MakeSimpleColumnDefNode(
115+
def.GetColname(), def.GetTypeName(), []*pg_query.Node{constraints[index]}, def.GetLocation()),
116+
Behavior: 0,
117+
MissingOk: false,
118+
},
119+
},
120+
}*/
121+
122+
/* newStmt := &pg_query.RawStmt{
123+
Stmt: &pg_query.Node{
124+
Node: &pg_query.Node_AlterTableStmt{
125+
AlterTableStmt: &pg_query.AlterTableStmt{
126+
Relation: stmt.AlterTableStmt.GetRelation(),
127+
Cmds: []*pg_query.Node{newCmd},
128+
Relkind: 0,
129+
MissingOk: false,
130+
},
131+
},
132+
},
133+
StmtLocation: 0,
134+
StmtLen: 0,
135+
}*/
136+
137+
setDef := fmt.Sprintf(`ALTER TABLE %s ALTER COLUMN %s SET DEFAULT %v;`,
138+
stmt.AlterTableStmt.GetRelation().GetRelname(), def.Colname,
139+
constraints[index].GetConstraint().GetRawExpr().GetAConst().GetVal().GetInteger().GetIval())
140+
fmt.Println(setDef)
141+
142+
scanDef, err := pg_query.Parse(setDef)
143+
if err != nil {
144+
log.Fatal(err)
145+
}
146+
147+
stmts = append(stmts, scanDef.Stmts...)
148+
149+
// TODO: Update rows
150+
151+
// TODO: apply the rest constraints
152+
constraints = append(constraints[:index], constraints[index+1:]...)
153+
154+
//commands = append(commands, newCmd)
155+
}
156+
157+
default:
158+
cmd.Node = v
159+
}
160+
161+
default:
162+
commands = append(commands, cmd)
163+
164+
fmt.Printf("%T\n", v)
165+
}
166+
}
167+
168+
stmt.AlterTableStmt.Cmds = commands
169+
}

engine/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ require (
1717
github.com/jackc/pgtype v1.5.0
1818
github.com/jackc/pgx/v4 v4.9.0
1919
github.com/lib/pq v1.8.0
20+
github.com/pganalyze/pg_query_go/v2 v2.1.0
2021
github.com/pkg/errors v0.9.1
2122
github.com/robfig/cron/v3 v3.0.1
2223
github.com/rs/xid v1.2.1

engine/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,8 @@ github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqi
548548
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
549549
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
550550
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
551+
github.com/pganalyze/pg_query_go/v2 v2.1.0 h1:donwPZ4G/X+kMs7j5eYtKjdziqyOLVp3pkUrzb9lDl8=
552+
github.com/pganalyze/pg_query_go/v2 v2.1.0/go.mod h1:XAxmVqz1tEGqizcQ3YSdN90vCOHBWjJi8URL1er5+cA=
551553
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
552554
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
553555
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

0 commit comments

Comments
 (0)