Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
myhau committed Jun 7, 2024
1 parent b6dd6a5 commit 067b90e
Show file tree
Hide file tree
Showing 11 changed files with 449 additions and 3 deletions.
6 changes: 3 additions & 3 deletions _examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ require github.com/goccy/go-zetasqlite v0.6.6

require (
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/goccy/go-json v0.9.10 // indirect
github.com/goccy/go-zetasql v0.3.3 // indirect
github.com/goccy/go-json v0.10.0 // indirect
github.com/goccy/go-zetasql v0.5.5 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/mattn/go-sqlite3 v1.14.14 // indirect
github.com/mattn/go-sqlite3 v1.14.16 // indirect
gonum.org/v1/gonum v0.11.0 // indirect
)

Expand Down
3 changes: 3 additions & 0 deletions _examples/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/goccy/go-json v0.9.10 h1:hCeNmprSNLB8B8vQKWl6DpuH0t60oEs+TAk9a7CScKc=
github.com/goccy/go-json v0.9.10/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-zetasql v0.3.3 h1:+Ar/GZ4k2vNgaljRPt5lpD8JSIiq0WSEG38Fbowj5fM=
github.com/goccy/go-zetasql v0.3.3/go.mod h1:6W14CJVKh7crrSPyj6NPk4c49L2NWnxvyDLsRkOm4BI=
github.com/goccy/go-zetasql v0.5.5/go.mod h1:xvvooX2RG404vnbdFZuAM8bTFksYwVUlqeIUrUNuo40=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw=
github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3 h1:n9HxLrNxWWtEb1cA950nuEEj3QnKbtsCJ6KjcgisNUs=
gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E=
gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA=
28 changes: 28 additions & 0 deletions compile-tests-and-run-with-delve.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash

pkill dlv

#tmux split-window -h -t main:0

# Send the script execution command to the second pane (index 1)
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

# Attach to the tmux session
#tmux attach-session -t my_session

PORT=2345 # The port to check
DELAY=1 # Number of seconds to wait between checks

# Function to check if the port is being used
check_port() {
lsof -iTCP:$PORT -sTCP:LISTEN -t >/dev/null
}

# Loop until the program is listening on the port
while ! check_port; do
echo "Waiting for the program to start listening on port $PORT..."
sleep $DELAY
done

# Program is now listening
echo "The program is now listening on port $PORT."
28 changes: 28 additions & 0 deletions compile-tests-and-run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash

pkill dlv

#tmux split-window -h -t main:0

# Send the script execution command to the second pane (index 1)
tmux send-keys -t main:0.0 ' go test -c 2>&1 | logsane-cli && ./go-zetasqlite.test | lnav -n' Enter

# Attach to the tmux session
#tmux attach-session -t my_session

#PORT=2345 # The port to check
#DELAY=1 # Number of seconds to wait between checks
#
## Function to check if the port is being used
#check_port() {
# lsof -iTCP:$PORT -sTCP:LISTEN -t >/dev/null
#}
#
## Loop until the program is listening on the port
#while ! check_port; do
# echo "Waiting for the program to start listening on port $PORT..."
# sleep $DELAY
#done
#
## Program is now listening
#echo "The program is now listening on port $PORT."
212 changes: 212 additions & 0 deletions driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,218 @@ import (
zetasqlite "github.com/goccy/go-zetasqlite"
)

func TestDriverAlter(t *testing.T) {
db, err := sql.Open("zetasqlite", ":memory:")
if err != nil {
t.Fatal(err)
}
if _, err := db.Exec(`
CREATE TABLE IF NOT EXISTS Singers (
SingerId INT64 NOT NULL,
FirstName STRING(1024),
LastName STRING(1024),
SingerInfo BYTES(MAX)
)`); err != nil {
t.Fatal(err)
}
if _, err := db.Exec(`INSERT Singers (SingerId, FirstName, LastName) VALUES (1, 'John', 'Titor')`); err != nil {
t.Fatal(err)
}
row := db.QueryRow("SELECT SingerId, FirstName, LastName FROM Singers WHERE SingerId = @id", 1)
if row.Err() != nil {
t.Fatal(row.Err())
}
var (
singerID int64
firstName string
lastName string
)
if err := row.Scan(&singerID, &firstName, &lastName); err != nil {
t.Fatal(err)
}
if singerID != 1 || firstName != "John" || lastName != "Titor" {
t.Fatalf("failed to find row %v %v %v", singerID, firstName, lastName)
}

if _, err := db.Exec(`
CREATE VIEW IF NOT EXISTS SingerNames AS SELECT FirstName || ' ' || LastName AS Name FROM Singers`); err != nil {
t.Fatal(err)
}

viewRow := db.QueryRow("SELECT Name FROM SingerNames LIMIT 1")
if viewRow.Err() != nil {
t.Fatal(viewRow.Err())
}

var name string

if err := viewRow.Scan(&name); err != nil {
t.Fatal(err)
}
if name != "John Titor" {
t.Fatalf("failed to find view row")
}

// Test ALTER TABLE SET OPTIONS
if _, err := db.Exec(`ALTER TABLE Singers SET OPTIONS (description="Famous singers")`); err != nil {
t.Fatal(err)
}

// Test ALTER TABLE ADD COLUMN
if _, err := db.Exec(`ALTER TABLE Singers ADD COLUMN Age INT64, ADD COLUMN IsSingle BOOL`); err != nil {
t.Fatal(err)
}

// Verify the changes
row = db.QueryRow("SELECT SingerId, FirstName, LastName, Age, IsSingle FROM Singers WHERE SingerId = @id", 1)
if row.Err() != nil {
t.Fatal(row.Err())
}

var age sql.NullInt64
var isSingle sql.NullBool
if err := row.Scan(&singerID, &firstName, &lastName, &age, &isSingle); err != nil {
t.Fatal(err)
}
if singerID != 1 || firstName != "John" || lastName != "Titor" || age.Valid || isSingle.Valid {
t.Fatalf("failed to find row after ALTER TABLE statements")
}

if _, err := db.Exec(`INSERT Singers (SingerId, FirstName, LastName, Age, IsSingle) VALUES (1, 'John', 'Titor', 10, TRUE)`); err != nil {
t.Fatal(err)
}
row = db.QueryRow("SELECT SingerId, FirstName, LastName, Age, isSingle FROM Singers WHERE SingerId = @id AND isSingle IS NOT NULL", 1)
if row.Err() != nil {
t.Fatal(row.Err())
}
if err := row.Scan(&singerID, &firstName, &lastName, &age, &isSingle); err != nil {
t.Fatal(err)
}
if singerID != 1 || firstName != "John" || lastName != "Titor" || age.Int64 != 10 || isSingle.Bool != true {
t.Fatalf("failed to find row %v %v %v %v %v", singerID, firstName, lastName, age, isSingle)
}

if _, err := db.Exec(`
ALTER TABLE Artists
ADD COLUMN Age INT64,
ADD COLUMN Nationality STRING NOT NULL DEFAULT 'Unknown',
DROP COLUMN LastName,
RENAME COLUMN GivenName TO FirstName
RENAME TO Musicians
`); err != nil {
t.Fatal(err)
}

// Verify the changes
row = db.QueryRow("SELECT SingerID, FirstName, Age, Nationality FROM Musicians WHERE SingerId = @id", 1)
if row.Err() != nil {
t.Fatal(row.Err())
}

//var nationality sql.NullString
//if err := row.Scan(&singerID, &firstName, &lastName, &age, &nationality); err != nil {
// t.Fatal(err)
//}
//if singerID != 1 || firstName != "John" || lastName != "Titor" || age.Valid || nationality.Valid {
// t.Fatalf("failed to find row after multi-action ALTER TABLE statement")
//}
}

func TestDriverAlter2(t *testing.T) {
db, err := sql.Open("zetasqlite", ":memory:")
if err != nil {
t.Fatal(err)
}
if _, err := db.Exec(`
CREATE TABLE IF NOT EXISTS Singers (
SingerId INT64 NOT NULL,
FirstName STRING(1024),
LastName STRING(1024),
SingerInfo BYTES(MAX)
)`); err != nil {
t.Fatal(err)
}
if _, err := db.Exec(`INSERT Singers (SingerId, FirstName, LastName) VALUES (1, 'John', 'Titor')`); err != nil {
t.Fatal(err)
}
row := db.QueryRow("SELECT SingerId, FirstName, LastName FROM Singers WHERE SingerId = @id", 1)
if row.Err() != nil {
t.Fatal(row.Err())
}
var (
singerID int64
firstName string
lastName string
)
if err := row.Scan(&singerID, &firstName, &lastName); err != nil {
t.Fatal(err)
}
if singerID != 1 || firstName != "John" || lastName != "Titor" {
t.Fatalf("failed to find row %v %v %v", singerID, firstName, lastName)
}

if _, err := db.Exec(`
CREATE VIEW IF NOT EXISTS SingerNames AS SELECT FirstName || ' ' || LastName AS Name FROM Singers`); err != nil {
t.Fatal(err)
}

viewRow := db.QueryRow("SELECT Name FROM SingerNames LIMIT 1")
if viewRow.Err() != nil {
t.Fatal(viewRow.Err())
}

var name string

if err := viewRow.Scan(&name); err != nil {
t.Fatal(err)
}
if name != "John Titor" {
t.Fatalf("failed to find view row")
}

// Test ALTER TABLE SET OPTIONS
//if _, err := db.Exec(`ALTER TABLE Singers SET OPTIONS (description="Famous singers")`); err != nil {
// t.Fatal(err)
//}
//
//// Test ALTER TABLE ADD COLUMN
//if _, err := db.Exec(`ALTER TABLE Singers ADD COLUMN Age INT64`); err != nil {
// t.Fatal(err)
//}

//// Test ALTER TABLE RENAME COLUMN
//if _, err := db.Exec(`ALTER TABLE Singers RENAME COLUMN FirstName TO GivenName`); err != nil {
// t.Fatal(err)
//}

// Test ALTER TABLE DROP COLUMN
//if _, err := db.Exec(`ALTER TABLE Singers DROP COLUMN SingerInfo`); err != nil {
// t.Fatal(err)
//}

if _, err := db.Exec(`
ALTER TABLE Singers
ADD COLUMN Age INT64,
ADD COLUMN Nationality STRING
`); err != nil {
t.Fatal(err)
}

// Verify the changes
row = db.QueryRow("SELECT SingerId, FirstName, Age, Nationality FROM Singers WHERE SingerId = @id", 1)
if row.Err() != nil {
t.Fatal(row.Err())
}

//var nationality sql.NullString
//if err := row.Scan(&singerID, &firstName, &lastName, &age, &nationality); err != nil {
// t.Fatal(err)
//}
//if singerID != 1 || firstName != "John" || lastName != "Titor" || age.Valid || nationality.Valid {
// t.Fatalf("failed to find row after multi-action ALTER TABLE statement")
//}
}

func TestDriver(t *testing.T) {
db, err := sql.Open("zetasqlite", ":memory:")
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ require (
cloud.google.com/go/bigquery v1.51.0
github.com/DataDog/go-hll v1.0.2
github.com/dop251/goja v0.0.0-20221118162653-d4bf6fde1b86
github.com/gdexlab/go-render v1.0.1
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72
golang.org/x/net v0.8.0
golang.org/x/text v0.8.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/gdexlab/go-render v1.0.1 h1:rxqB3vo5s4n1kF0ySmoNeSPRYkEsyHgln4jFIQY7v0U=
github.com/gdexlab/go-render v1.0.1/go.mod h1:wRi5nW2qfjiGj4mPukH4UV0IknS1cHD4VgFTmJX5JzM=
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
Expand Down
24 changes: 24 additions & 0 deletions internal/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ func newAnalyzerOptions() (*zetasql.AnalyzerOptions, error) {
ast.DropStmt,
ast.TruncateStmt,
ast.CreateTableStmt,
ast.AlterTableStmt, // TODO: (mfudala) add more
ast.RenameStmt,
ast.CreateTableAsSelectStmt,
ast.CreateProcedureStmt,
ast.CreateFunctionStmt,
Expand Down Expand Up @@ -290,10 +292,32 @@ func (a *Analyzer) newStmtAction(ctx context.Context, query string, args []drive
return a.newBeginStmtAction(ctx, query, args, node)
case ast.CommitStmt:
return a.newCommitStmtAction(ctx, query, args, node)
case ast.AlterTableStmt:
return a.alterTableStmtAction(ctx, query, args, node.(*ast.AlterTableStmtNode))
}
return nil, fmt.Errorf("unsupported stmt %s", node.DebugString())
}

func (a *Analyzer) alterTableStmtAction(_ context.Context, query string, args []driver.NamedValue, node *ast.AlterTableStmtNode) (*AlterTableStmtAction, error) {
spec, err := newAlterSpec(a.namePath, node)
if err != nil {
return nil, err
}
params := getParamsFromNode(node)
queryArgs, err := getArgsFromParams(args, params)
if err != nil {
return nil, err
}
return &AlterTableStmtAction{
query: query,
spec: spec,
node: node,
args: queryArgs,
rawArgs: args,
catalog: a.catalog,
}, nil
}

func (a *Analyzer) newCreateTableStmtAction(_ context.Context, query string, args []driver.NamedValue, node *ast.CreateTableStmtNode) (*CreateTableStmtAction, error) {
spec := newTableSpec(a.namePath, node)
params := getParamsFromNode(node)
Expand Down
Loading

0 comments on commit 067b90e

Please sign in to comment.