Skip to content

Commit 067b90e

Browse files
committed
wip
1 parent b6dd6a5 commit 067b90e

11 files changed

+449
-3
lines changed

_examples/go.mod

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ require github.com/goccy/go-zetasqlite v0.6.6
66

77
require (
88
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
9-
github.com/goccy/go-json v0.9.10 // indirect
10-
github.com/goccy/go-zetasql v0.3.3 // indirect
9+
github.com/goccy/go-json v0.10.0 // indirect
10+
github.com/goccy/go-zetasql v0.5.5 // indirect
1111
github.com/google/uuid v1.3.0 // indirect
12-
github.com/mattn/go-sqlite3 v1.14.14 // indirect
12+
github.com/mattn/go-sqlite3 v1.14.16 // indirect
1313
gonum.org/v1/gonum v0.11.0 // indirect
1414
)
1515

_examples/go.sum

+3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA
22
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
33
github.com/goccy/go-json v0.9.10 h1:hCeNmprSNLB8B8vQKWl6DpuH0t60oEs+TAk9a7CScKc=
44
github.com/goccy/go-json v0.9.10/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
5+
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
56
github.com/goccy/go-zetasql v0.3.3 h1:+Ar/GZ4k2vNgaljRPt5lpD8JSIiq0WSEG38Fbowj5fM=
67
github.com/goccy/go-zetasql v0.3.3/go.mod h1:6W14CJVKh7crrSPyj6NPk4c49L2NWnxvyDLsRkOm4BI=
8+
github.com/goccy/go-zetasql v0.5.5/go.mod h1:xvvooX2RG404vnbdFZuAM8bTFksYwVUlqeIUrUNuo40=
79
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
810
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
911
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
1012
github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw=
1113
github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
14+
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
1215
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3 h1:n9HxLrNxWWtEb1cA950nuEEj3QnKbtsCJ6KjcgisNUs=
1316
gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E=
1417
gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA=

compile-tests-and-run-with-delve.sh

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/bash
2+
3+
pkill dlv
4+
5+
#tmux split-window -h -t main:0
6+
7+
# Send the script execution command to the second pane (index 1)
8+
tmux send-keys -t main:0.0 'go test -c && dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./go-zetasqlite.test' Enter
9+
10+
# Attach to the tmux session
11+
#tmux attach-session -t my_session
12+
13+
PORT=2345 # The port to check
14+
DELAY=1 # Number of seconds to wait between checks
15+
16+
# Function to check if the port is being used
17+
check_port() {
18+
lsof -iTCP:$PORT -sTCP:LISTEN -t >/dev/null
19+
}
20+
21+
# Loop until the program is listening on the port
22+
while ! check_port; do
23+
echo "Waiting for the program to start listening on port $PORT..."
24+
sleep $DELAY
25+
done
26+
27+
# Program is now listening
28+
echo "The program is now listening on port $PORT."

compile-tests-and-run.sh

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/bash
2+
3+
pkill dlv
4+
5+
#tmux split-window -h -t main:0
6+
7+
# Send the script execution command to the second pane (index 1)
8+
tmux send-keys -t main:0.0 ' go test -c 2>&1 | logsane-cli && ./go-zetasqlite.test | lnav -n' Enter
9+
10+
# Attach to the tmux session
11+
#tmux attach-session -t my_session
12+
13+
#PORT=2345 # The port to check
14+
#DELAY=1 # Number of seconds to wait between checks
15+
#
16+
## Function to check if the port is being used
17+
#check_port() {
18+
# lsof -iTCP:$PORT -sTCP:LISTEN -t >/dev/null
19+
#}
20+
#
21+
## Loop until the program is listening on the port
22+
#while ! check_port; do
23+
# echo "Waiting for the program to start listening on port $PORT..."
24+
# sleep $DELAY
25+
#done
26+
#
27+
## Program is now listening
28+
#echo "The program is now listening on port $PORT."

driver_test.go

+212
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,218 @@ import (
1010
zetasqlite "github.com/goccy/go-zetasqlite"
1111
)
1212

13+
func TestDriverAlter(t *testing.T) {
14+
db, err := sql.Open("zetasqlite", ":memory:")
15+
if err != nil {
16+
t.Fatal(err)
17+
}
18+
if _, err := db.Exec(`
19+
CREATE TABLE IF NOT EXISTS Singers (
20+
SingerId INT64 NOT NULL,
21+
FirstName STRING(1024),
22+
LastName STRING(1024),
23+
SingerInfo BYTES(MAX)
24+
)`); err != nil {
25+
t.Fatal(err)
26+
}
27+
if _, err := db.Exec(`INSERT Singers (SingerId, FirstName, LastName) VALUES (1, 'John', 'Titor')`); err != nil {
28+
t.Fatal(err)
29+
}
30+
row := db.QueryRow("SELECT SingerId, FirstName, LastName FROM Singers WHERE SingerId = @id", 1)
31+
if row.Err() != nil {
32+
t.Fatal(row.Err())
33+
}
34+
var (
35+
singerID int64
36+
firstName string
37+
lastName string
38+
)
39+
if err := row.Scan(&singerID, &firstName, &lastName); err != nil {
40+
t.Fatal(err)
41+
}
42+
if singerID != 1 || firstName != "John" || lastName != "Titor" {
43+
t.Fatalf("failed to find row %v %v %v", singerID, firstName, lastName)
44+
}
45+
46+
if _, err := db.Exec(`
47+
CREATE VIEW IF NOT EXISTS SingerNames AS SELECT FirstName || ' ' || LastName AS Name FROM Singers`); err != nil {
48+
t.Fatal(err)
49+
}
50+
51+
viewRow := db.QueryRow("SELECT Name FROM SingerNames LIMIT 1")
52+
if viewRow.Err() != nil {
53+
t.Fatal(viewRow.Err())
54+
}
55+
56+
var name string
57+
58+
if err := viewRow.Scan(&name); err != nil {
59+
t.Fatal(err)
60+
}
61+
if name != "John Titor" {
62+
t.Fatalf("failed to find view row")
63+
}
64+
65+
// Test ALTER TABLE SET OPTIONS
66+
if _, err := db.Exec(`ALTER TABLE Singers SET OPTIONS (description="Famous singers")`); err != nil {
67+
t.Fatal(err)
68+
}
69+
70+
// Test ALTER TABLE ADD COLUMN
71+
if _, err := db.Exec(`ALTER TABLE Singers ADD COLUMN Age INT64, ADD COLUMN IsSingle BOOL`); err != nil {
72+
t.Fatal(err)
73+
}
74+
75+
// Verify the changes
76+
row = db.QueryRow("SELECT SingerId, FirstName, LastName, Age, IsSingle FROM Singers WHERE SingerId = @id", 1)
77+
if row.Err() != nil {
78+
t.Fatal(row.Err())
79+
}
80+
81+
var age sql.NullInt64
82+
var isSingle sql.NullBool
83+
if err := row.Scan(&singerID, &firstName, &lastName, &age, &isSingle); err != nil {
84+
t.Fatal(err)
85+
}
86+
if singerID != 1 || firstName != "John" || lastName != "Titor" || age.Valid || isSingle.Valid {
87+
t.Fatalf("failed to find row after ALTER TABLE statements")
88+
}
89+
90+
if _, err := db.Exec(`INSERT Singers (SingerId, FirstName, LastName, Age, IsSingle) VALUES (1, 'John', 'Titor', 10, TRUE)`); err != nil {
91+
t.Fatal(err)
92+
}
93+
row = db.QueryRow("SELECT SingerId, FirstName, LastName, Age, isSingle FROM Singers WHERE SingerId = @id AND isSingle IS NOT NULL", 1)
94+
if row.Err() != nil {
95+
t.Fatal(row.Err())
96+
}
97+
if err := row.Scan(&singerID, &firstName, &lastName, &age, &isSingle); err != nil {
98+
t.Fatal(err)
99+
}
100+
if singerID != 1 || firstName != "John" || lastName != "Titor" || age.Int64 != 10 || isSingle.Bool != true {
101+
t.Fatalf("failed to find row %v %v %v %v %v", singerID, firstName, lastName, age, isSingle)
102+
}
103+
104+
if _, err := db.Exec(`
105+
ALTER TABLE Artists
106+
ADD COLUMN Age INT64,
107+
ADD COLUMN Nationality STRING NOT NULL DEFAULT 'Unknown',
108+
DROP COLUMN LastName,
109+
RENAME COLUMN GivenName TO FirstName
110+
RENAME TO Musicians
111+
`); err != nil {
112+
t.Fatal(err)
113+
}
114+
115+
// Verify the changes
116+
row = db.QueryRow("SELECT SingerID, FirstName, Age, Nationality FROM Musicians WHERE SingerId = @id", 1)
117+
if row.Err() != nil {
118+
t.Fatal(row.Err())
119+
}
120+
121+
//var nationality sql.NullString
122+
//if err := row.Scan(&singerID, &firstName, &lastName, &age, &nationality); err != nil {
123+
// t.Fatal(err)
124+
//}
125+
//if singerID != 1 || firstName != "John" || lastName != "Titor" || age.Valid || nationality.Valid {
126+
// t.Fatalf("failed to find row after multi-action ALTER TABLE statement")
127+
//}
128+
}
129+
130+
func TestDriverAlter2(t *testing.T) {
131+
db, err := sql.Open("zetasqlite", ":memory:")
132+
if err != nil {
133+
t.Fatal(err)
134+
}
135+
if _, err := db.Exec(`
136+
CREATE TABLE IF NOT EXISTS Singers (
137+
SingerId INT64 NOT NULL,
138+
FirstName STRING(1024),
139+
LastName STRING(1024),
140+
SingerInfo BYTES(MAX)
141+
)`); err != nil {
142+
t.Fatal(err)
143+
}
144+
if _, err := db.Exec(`INSERT Singers (SingerId, FirstName, LastName) VALUES (1, 'John', 'Titor')`); err != nil {
145+
t.Fatal(err)
146+
}
147+
row := db.QueryRow("SELECT SingerId, FirstName, LastName FROM Singers WHERE SingerId = @id", 1)
148+
if row.Err() != nil {
149+
t.Fatal(row.Err())
150+
}
151+
var (
152+
singerID int64
153+
firstName string
154+
lastName string
155+
)
156+
if err := row.Scan(&singerID, &firstName, &lastName); err != nil {
157+
t.Fatal(err)
158+
}
159+
if singerID != 1 || firstName != "John" || lastName != "Titor" {
160+
t.Fatalf("failed to find row %v %v %v", singerID, firstName, lastName)
161+
}
162+
163+
if _, err := db.Exec(`
164+
CREATE VIEW IF NOT EXISTS SingerNames AS SELECT FirstName || ' ' || LastName AS Name FROM Singers`); err != nil {
165+
t.Fatal(err)
166+
}
167+
168+
viewRow := db.QueryRow("SELECT Name FROM SingerNames LIMIT 1")
169+
if viewRow.Err() != nil {
170+
t.Fatal(viewRow.Err())
171+
}
172+
173+
var name string
174+
175+
if err := viewRow.Scan(&name); err != nil {
176+
t.Fatal(err)
177+
}
178+
if name != "John Titor" {
179+
t.Fatalf("failed to find view row")
180+
}
181+
182+
// Test ALTER TABLE SET OPTIONS
183+
//if _, err := db.Exec(`ALTER TABLE Singers SET OPTIONS (description="Famous singers")`); err != nil {
184+
// t.Fatal(err)
185+
//}
186+
//
187+
//// Test ALTER TABLE ADD COLUMN
188+
//if _, err := db.Exec(`ALTER TABLE Singers ADD COLUMN Age INT64`); err != nil {
189+
// t.Fatal(err)
190+
//}
191+
192+
//// Test ALTER TABLE RENAME COLUMN
193+
//if _, err := db.Exec(`ALTER TABLE Singers RENAME COLUMN FirstName TO GivenName`); err != nil {
194+
// t.Fatal(err)
195+
//}
196+
197+
// Test ALTER TABLE DROP COLUMN
198+
//if _, err := db.Exec(`ALTER TABLE Singers DROP COLUMN SingerInfo`); err != nil {
199+
// t.Fatal(err)
200+
//}
201+
202+
if _, err := db.Exec(`
203+
ALTER TABLE Singers
204+
ADD COLUMN Age INT64,
205+
ADD COLUMN Nationality STRING
206+
`); err != nil {
207+
t.Fatal(err)
208+
}
209+
210+
// Verify the changes
211+
row = db.QueryRow("SELECT SingerId, FirstName, Age, Nationality FROM Singers WHERE SingerId = @id", 1)
212+
if row.Err() != nil {
213+
t.Fatal(row.Err())
214+
}
215+
216+
//var nationality sql.NullString
217+
//if err := row.Scan(&singerID, &firstName, &lastName, &age, &nationality); err != nil {
218+
// t.Fatal(err)
219+
//}
220+
//if singerID != 1 || firstName != "John" || lastName != "Titor" || age.Valid || nationality.Valid {
221+
// t.Fatalf("failed to find row after multi-action ALTER TABLE statement")
222+
//}
223+
}
224+
13225
func TestDriver(t *testing.T) {
14226
db, err := sql.Open("zetasqlite", ":memory:")
15227
if err != nil {

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ require (
2121
cloud.google.com/go/bigquery v1.51.0
2222
github.com/DataDog/go-hll v1.0.2
2323
github.com/dop251/goja v0.0.0-20221118162653-d4bf6fde1b86
24+
github.com/gdexlab/go-render v1.0.1
2425
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72
2526
golang.org/x/net v0.8.0
2627
golang.org/x/text v0.8.0

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
4343
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
4444
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
4545
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
46+
github.com/gdexlab/go-render v1.0.1 h1:rxqB3vo5s4n1kF0ySmoNeSPRYkEsyHgln4jFIQY7v0U=
47+
github.com/gdexlab/go-render v1.0.1/go.mod h1:wRi5nW2qfjiGj4mPukH4UV0IknS1cHD4VgFTmJX5JzM=
4648
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
4749
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
4850
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=

internal/analyzer.go

+24
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ func newAnalyzerOptions() (*zetasql.AnalyzerOptions, error) {
8787
ast.DropStmt,
8888
ast.TruncateStmt,
8989
ast.CreateTableStmt,
90+
ast.AlterTableStmt, // TODO: (mfudala) add more
91+
ast.RenameStmt,
9092
ast.CreateTableAsSelectStmt,
9193
ast.CreateProcedureStmt,
9294
ast.CreateFunctionStmt,
@@ -290,10 +292,32 @@ func (a *Analyzer) newStmtAction(ctx context.Context, query string, args []drive
290292
return a.newBeginStmtAction(ctx, query, args, node)
291293
case ast.CommitStmt:
292294
return a.newCommitStmtAction(ctx, query, args, node)
295+
case ast.AlterTableStmt:
296+
return a.alterTableStmtAction(ctx, query, args, node.(*ast.AlterTableStmtNode))
293297
}
294298
return nil, fmt.Errorf("unsupported stmt %s", node.DebugString())
295299
}
296300

301+
func (a *Analyzer) alterTableStmtAction(_ context.Context, query string, args []driver.NamedValue, node *ast.AlterTableStmtNode) (*AlterTableStmtAction, error) {
302+
spec, err := newAlterSpec(a.namePath, node)
303+
if err != nil {
304+
return nil, err
305+
}
306+
params := getParamsFromNode(node)
307+
queryArgs, err := getArgsFromParams(args, params)
308+
if err != nil {
309+
return nil, err
310+
}
311+
return &AlterTableStmtAction{
312+
query: query,
313+
spec: spec,
314+
node: node,
315+
args: queryArgs,
316+
rawArgs: args,
317+
catalog: a.catalog,
318+
}, nil
319+
}
320+
297321
func (a *Analyzer) newCreateTableStmtAction(_ context.Context, query string, args []driver.NamedValue, node *ast.CreateTableStmtNode) (*CreateTableStmtAction, error) {
298322
spec := newTableSpec(a.namePath, node)
299323
params := getParamsFromNode(node)

0 commit comments

Comments
 (0)