diff --git a/go.mod b/go.mod index 50e172e..28a6cae 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/goccy/go-json v0.10.0 github.com/goccy/go-yaml v1.9.5 github.com/goccy/go-zetasql v0.5.1 - github.com/goccy/go-zetasqlite v0.16.0 + github.com/goccy/go-zetasqlite v0.17.0 github.com/google/go-cmp v0.5.9 github.com/googleapis/gax-go/v2 v2.7.1 github.com/gorilla/mux v1.8.0 diff --git a/go.sum b/go.sum index d29350f..aa4a2b2 100644 --- a/go.sum +++ b/go.sum @@ -79,8 +79,8 @@ github.com/goccy/go-yaml v1.9.5 h1:Eh/+3uk9kLxG4koCX6lRMAPS1OaMSAi+FJcya0INdB0= github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= github.com/goccy/go-zetasql v0.5.1 h1:vP9wgUH5gylw8yL+gwO0wF7uW/fW5Dr1AAAzi8Kgevg= github.com/goccy/go-zetasql v0.5.1/go.mod h1:6W14CJVKh7crrSPyj6NPk4c49L2NWnxvyDLsRkOm4BI= -github.com/goccy/go-zetasqlite v0.16.0 h1:kjd6g8tY1OIEefCHjeZYvfu0tQwVswEaYHR844XFTLY= -github.com/goccy/go-zetasqlite v0.16.0/go.mod h1:ikLN7nRFum4sXL6kDxgIWrhH/9iZSdwXWXZzMUnuTjM= +github.com/goccy/go-zetasqlite v0.17.0 h1:bz+YQHl5a35gMPlPdMiiTstjNHHPR8A5uQvAaD84W/g= +github.com/goccy/go-zetasqlite v0.17.0/go.mod h1:ikLN7nRFum4sXL6kDxgIWrhH/9iZSdwXWXZzMUnuTjM= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= diff --git a/internal/connection/manager.go b/internal/connection/manager.go index f7e753c..14d4d5d 100644 --- a/internal/connection/manager.go +++ b/internal/connection/manager.go @@ -69,7 +69,7 @@ func (t *Tx) MetadataRepoMode() error { if !ok { return fmt.Errorf("failed to get ZetaSQLiteConn from %T", c) } - zetasqliteConn.SetNamePath([]string{}) + _ = zetasqliteConn.SetNamePath([]string{}) return nil }); err != nil { return fmt.Errorf("failed to setup connection: %w", err) @@ -84,10 +84,12 @@ func (t *Tx) ContentRepoMode() error { return fmt.Errorf("failed to get ZetaSQLiteConn from %T", c) } if t.conn.DatasetID == "" { - zetasqliteConn.SetNamePath([]string{t.conn.ProjectID}) + _ = zetasqliteConn.SetNamePath([]string{t.conn.ProjectID}) } else { - zetasqliteConn.SetNamePath([]string{t.conn.ProjectID, t.conn.DatasetID}) + _ = zetasqliteConn.SetNamePath([]string{t.conn.ProjectID, t.conn.DatasetID}) } + const maxNamePath = 3 // projectID and datasetID and tableID + zetasqliteConn.SetMaxNamePath(maxNamePath) return nil }); err != nil { return fmt.Errorf("failed to setup connection: %w", err) diff --git a/internal/contentdata/repository.go b/internal/contentdata/repository.go index f9f712e..5e209fe 100644 --- a/internal/contentdata/repository.go +++ b/internal/contentdata/repository.go @@ -42,10 +42,12 @@ func (r *Repository) getConnection(ctx context.Context, projectID, datasetID str return fmt.Errorf("failed to get ZetaSQLiteConn from %T", c) } if datasetID == "" { - zetasqliteConn.SetNamePath([]string{projectID}) + _ = zetasqliteConn.SetNamePath([]string{projectID}) } else { - zetasqliteConn.SetNamePath([]string{projectID, datasetID}) + _ = zetasqliteConn.SetNamePath([]string{projectID, datasetID}) } + const maxNamePath = 3 // projectID and datasetID and tableID + zetasqliteConn.SetMaxNamePath(maxNamePath) return nil }); err != nil { return nil, fmt.Errorf("failed to setup connection: %w", err) diff --git a/server/server_test.go b/server/server_test.go index 85af865..28f0517 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -2116,3 +2116,96 @@ ORDER BY qty DESC;`) t.Fatal("failed to get result") } } + +func TestMultipleProject(t *testing.T) { + const ( + mainProjectID = "main_project" + mainDatasetID = "main_dataset" + mainTableID = "main_table" + subProjectID = "sub_project" + subDatasetID = "sub_dataset" + subTableID = "sub_table" + ) + + ctx := context.Background() + + bqServer, err := server.New(server.TempStorage) + if err != nil { + t.Fatal(err) + } + if err := bqServer.Load( + server.StructSource( + types.NewProject( + mainProjectID, + types.NewDataset( + mainDatasetID, + types.NewTable( + mainTableID, + []*types.Column{ + types.NewColumn("name", types.STRING), + }, + types.Data{ + {"name": "main-project-name-data"}, + }, + ), + ), + ), + ), + server.StructSource( + types.NewProject( + subProjectID, + types.NewDataset( + subDatasetID, + types.NewTable( + subTableID, + []*types.Column{ + types.NewColumn("name", types.STRING), + }, + types.Data{ + {"name": "sub-project-name-data"}, + }, + ), + ), + ), + ), + ); err != nil { + t.Fatal(err) + } + testServer := bqServer.TestServer() + defer func() { + testServer.Close() + bqServer.Stop(ctx) + }() + + client, err := bigquery.NewClient( + ctx, + mainProjectID, + option.WithEndpoint(testServer.URL), + option.WithoutAuthentication(), + ) + if err != nil { + t.Fatal(err) + } + defer client.Close() + + it, err := client.Query("SELECT * FROM sub_project.sub_dataset.sub_table").Read(ctx) + if err != nil { + t.Fatal(err) + } + var row []bigquery.Value + if err := it.Next(&row); err != nil { + if err != iterator.Done { + t.Fatal(err) + } + } + if len(row) != 1 { + t.Fatalf("failed to get row. got length %d", len(row)) + } + name, ok := row[0].(string) + if !ok { + t.Fatalf("failed to get row[0]. type is %T", row[0]) + } + if name != "sub-project-name-data" { + t.Fatalf("failed to get data from sub project: %s", name) + } +}