From 972469b3ce1594a379a992dbf3c52d48327d1346 Mon Sep 17 00:00:00 2001 From: David Coe Date: Thu, 26 Sep 2024 21:55:06 -0400 Subject: [PATCH 1/4] add support for null catalog --- go/adbc/driver/snowflake/connection.go | 48 +++++++++++++------ go/adbc/driver/snowflake/driver_test.go | 8 ++++ .../queries/get_objects_terse_catalogs.sql | 24 ++++++++++ 3 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 go/adbc/driver/snowflake/queries/get_objects_terse_catalogs.sql diff --git a/go/adbc/driver/snowflake/connection.go b/go/adbc/driver/snowflake/connection.go index e6ec699384..7713e74517 100644 --- a/go/adbc/driver/snowflake/connection.go +++ b/go/adbc/driver/snowflake/connection.go @@ -41,10 +41,11 @@ const ( defaultStatementQueueSize = 200 defaultPrefetchConcurrency = 10 - queryTemplateGetObjectsAll = "get_objects_all.sql" - queryTemplateGetObjectsCatalogs = "get_objects_catalogs.sql" - queryTemplateGetObjectsDbSchemas = "get_objects_dbschemas.sql" - queryTemplateGetObjectsTables = "get_objects_tables.sql" + queryTemplateGetObjectsAll = "get_objects_all.sql" + queryTemplateGetObjectsCatalogs = "get_objects_catalogs.sql" + queryTemplateGetObjectsDbSchemas = "get_objects_dbschemas.sql" + queryTemplateGetObjectsTables = "get_objects_tables.sql" + queryTemplateGetObjectsTerseCatalogs = "get_objects_terse_catalogs.sql" ) //go:embed queries/* @@ -74,7 +75,7 @@ type connectionImpl struct { func (c *connectionImpl) GetObjects(ctx context.Context, depth adbc.ObjectDepth, catalog *string, dbSchema *string, tableName *string, columnName *string, tableType []string) (array.RecordReader, error) { var ( - pkQueryID, fkQueryID, uniqueQueryID string + pkQueryID, fkQueryID, uniqueQueryID, terseDbQueryID string ) conn, err := c.sqldb.Conn(ctx) @@ -83,11 +84,28 @@ func (c *connectionImpl) GetObjects(ctx context.Context, depth adbc.ObjectDepth, } defer conn.Close() - gConstraints, gContraintsCtx := errgroup.WithContext(ctx) + gQueryIDs, gQueryIDsCtx := errgroup.WithContext(ctx) queryFile := queryTemplateGetObjectsAll switch depth { case adbc.ObjectDepthCatalogs: - queryFile = queryTemplateGetObjectsCatalogs + if catalog == nil { + queryFile = queryTemplateGetObjectsTerseCatalogs + // if the catalog is null, show the terse databases + // which doesn't require a database context + gQueryIDs.Go(func() error { + return conn.Raw(func(driverConn any) error { + rows, err := driverConn.(driver.QueryerContext).QueryContext(context.Background(), "SHOW TERSE DATABASES", nil) + if err != nil { + return err + } + + terseDbQueryID = rows.(gosnowflake.SnowflakeRows).GetQueryID() + return rows.Close() + }) + }) + } else { + queryFile = queryTemplateGetObjectsCatalogs + } case adbc.ObjectDepthDBSchemas: queryFile = queryTemplateGetObjectsDbSchemas case adbc.ObjectDepthTables: @@ -96,9 +114,9 @@ func (c *connectionImpl) GetObjects(ctx context.Context, depth adbc.ObjectDepth, default: // Detailed constraint info not available in information_schema // Need to dispatch SHOW queries and use conn.Raw to extract the queryID for reuse in GetObjects query - gConstraints.Go(func() error { + gQueryIDs.Go(func() error { return conn.Raw(func(driverConn any) error { - rows, err := driverConn.(driver.QueryerContext).QueryContext(gContraintsCtx, "SHOW PRIMARY KEYS", nil) + rows, err := driverConn.(driver.QueryerContext).QueryContext(gQueryIDsCtx, "SHOW PRIMARY KEYS", nil) if err != nil { return err } @@ -108,9 +126,9 @@ func (c *connectionImpl) GetObjects(ctx context.Context, depth adbc.ObjectDepth, }) }) - gConstraints.Go(func() error { + gQueryIDs.Go(func() error { return conn.Raw(func(driverConn any) error { - rows, err := driverConn.(driver.QueryerContext).QueryContext(gContraintsCtx, "SHOW IMPORTED KEYS", nil) + rows, err := driverConn.(driver.QueryerContext).QueryContext(gQueryIDsCtx, "SHOW IMPORTED KEYS", nil) if err != nil { return err } @@ -120,9 +138,9 @@ func (c *connectionImpl) GetObjects(ctx context.Context, depth adbc.ObjectDepth, }) }) - gConstraints.Go(func() error { + gQueryIDs.Go(func() error { return conn.Raw(func(driverConn any) error { - rows, err := driverConn.(driver.QueryerContext).QueryContext(gContraintsCtx, "SHOW UNIQUE KEYS", nil) + rows, err := driverConn.(driver.QueryerContext).QueryContext(gQueryIDsCtx, "SHOW UNIQUE KEYS", nil) if err != nil { return err } @@ -145,7 +163,7 @@ func (c *connectionImpl) GetObjects(ctx context.Context, depth adbc.ObjectDepth, } // Need constraint subqueries to complete before we can query GetObjects - if err := gConstraints.Wait(); err != nil { + if err := gQueryIDs.Wait(); err != nil { return nil, err } @@ -157,9 +175,11 @@ func (c *connectionImpl) GetObjects(ctx context.Context, depth adbc.ObjectDepth, driverbase.PatternToNamedArg("COLUMN", columnName), // QueryIDs for constraint data if depth is tables or deeper + // or if the depth is catalog and catalog is null sql.Named("PK_QUERY_ID", pkQueryID), sql.Named("FK_QUERY_ID", fkQueryID), sql.Named("UNIQUE_QUERY_ID", uniqueQueryID), + sql.Named("TERSE_QUERY_ID", terseDbQueryID), } // the connection that is used is not the same connection context where the database may have been set diff --git a/go/adbc/driver/snowflake/driver_test.go b/go/adbc/driver/snowflake/driver_test.go index e56ce179a4..b539ec12cb 100644 --- a/go/adbc/driver/snowflake/driver_test.go +++ b/go/adbc/driver/snowflake/driver_test.go @@ -2144,3 +2144,11 @@ func (suite *SnowflakeTests) TestChangeDatabaseAndGetObjects() { _, err2 := suite.cnxn.GetObjects(suite.ctx, adbc.ObjectDepthAll, &newCatalog, &cfg.Schema, &getObjectsTable, nil, nil) suite.NoError(err2) } + +func (suite *SnowflakeTests) TestNilDatabaseAndGetObjects() { + // this test demonstrates: + // 1. having a null catalog + // 2. being able to call GetObjects with the catalog depth + _, err := suite.cnxn.GetObjects(suite.ctx, adbc.ObjectDepthCatalogs, nil, nil, nil, nil, nil) + suite.NoError(err) +} diff --git a/go/adbc/driver/snowflake/queries/get_objects_terse_catalogs.sql b/go/adbc/driver/snowflake/queries/get_objects_terse_catalogs.sql new file mode 100644 index 0000000000..5bc05feeb7 --- /dev/null +++ b/go/adbc/driver/snowflake/queries/get_objects_terse_catalogs.sql @@ -0,0 +1,24 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. + +-- SHOW TERSE DATABASES would run before this +SELECT + { + 'catalog_name': "name", + 'catalog_db_schemas': null + } get_objects +FROM TABLE(RESULT_SCAN(:TERSE_QUERY_ID)) From cf2297c9feac1db47a7ccd656f225677b6f3af86 Mon Sep 17 00:00:00 2001 From: David Coe Date: Thu, 26 Sep 2024 22:01:14 -0400 Subject: [PATCH 2/4] rename test method --- go/adbc/driver/snowflake/driver_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/adbc/driver/snowflake/driver_test.go b/go/adbc/driver/snowflake/driver_test.go index b539ec12cb..963bb96afb 100644 --- a/go/adbc/driver/snowflake/driver_test.go +++ b/go/adbc/driver/snowflake/driver_test.go @@ -2145,7 +2145,7 @@ func (suite *SnowflakeTests) TestChangeDatabaseAndGetObjects() { suite.NoError(err2) } -func (suite *SnowflakeTests) TestNilDatabaseAndGetObjects() { +func (suite *SnowflakeTests) TestGetObjectsWithNilCatalog() { // this test demonstrates: // 1. having a null catalog // 2. being able to call GetObjects with the catalog depth From 0c48c6ec89045d750d4b39cdc7ce6827bab061e3 Mon Sep 17 00:00:00 2001 From: David Coe Date: Fri, 27 Sep 2024 11:17:07 -0400 Subject: [PATCH 3/4] update context and comments --- go/adbc/driver/snowflake/connection.go | 2 +- go/adbc/driver/snowflake/driver_test.go | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/go/adbc/driver/snowflake/connection.go b/go/adbc/driver/snowflake/connection.go index 7713e74517..0e6d7ef995 100644 --- a/go/adbc/driver/snowflake/connection.go +++ b/go/adbc/driver/snowflake/connection.go @@ -94,7 +94,7 @@ func (c *connectionImpl) GetObjects(ctx context.Context, depth adbc.ObjectDepth, // which doesn't require a database context gQueryIDs.Go(func() error { return conn.Raw(func(driverConn any) error { - rows, err := driverConn.(driver.QueryerContext).QueryContext(context.Background(), "SHOW TERSE DATABASES", nil) + rows, err := driverConn.(driver.QueryerContext).QueryContext(gQueryIDsCtx, "SHOW TERSE DATABASES", nil) if err != nil { return err } diff --git a/go/adbc/driver/snowflake/driver_test.go b/go/adbc/driver/snowflake/driver_test.go index 963bb96afb..8ff66b1dab 100644 --- a/go/adbc/driver/snowflake/driver_test.go +++ b/go/adbc/driver/snowflake/driver_test.go @@ -2146,9 +2146,7 @@ func (suite *SnowflakeTests) TestChangeDatabaseAndGetObjects() { } func (suite *SnowflakeTests) TestGetObjectsWithNilCatalog() { - // this test demonstrates: - // 1. having a null catalog - // 2. being able to call GetObjects with the catalog depth + // this test demonstrates calling GetObjects with the catalog depth and a nil catalog _, err := suite.cnxn.GetObjects(suite.ctx, adbc.ObjectDepthCatalogs, nil, nil, nil, nil, nil) suite.NoError(err) } From 8a1c78237422b3132ae210769bc4e5ec3dcdce1f Mon Sep 17 00:00:00 2001 From: David Coe Date: Wed, 2 Oct 2024 10:28:21 -0400 Subject: [PATCH 4/4] rename parameter --- go/adbc/driver/snowflake/connection.go | 2 +- go/adbc/driver/snowflake/queries/get_objects_terse_catalogs.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go/adbc/driver/snowflake/connection.go b/go/adbc/driver/snowflake/connection.go index 0e6d7ef995..a8361a3653 100644 --- a/go/adbc/driver/snowflake/connection.go +++ b/go/adbc/driver/snowflake/connection.go @@ -179,7 +179,7 @@ func (c *connectionImpl) GetObjects(ctx context.Context, depth adbc.ObjectDepth, sql.Named("PK_QUERY_ID", pkQueryID), sql.Named("FK_QUERY_ID", fkQueryID), sql.Named("UNIQUE_QUERY_ID", uniqueQueryID), - sql.Named("TERSE_QUERY_ID", terseDbQueryID), + sql.Named("SHOW_DB_QUERY_ID", terseDbQueryID), } // the connection that is used is not the same connection context where the database may have been set diff --git a/go/adbc/driver/snowflake/queries/get_objects_terse_catalogs.sql b/go/adbc/driver/snowflake/queries/get_objects_terse_catalogs.sql index 5bc05feeb7..be56795e0b 100644 --- a/go/adbc/driver/snowflake/queries/get_objects_terse_catalogs.sql +++ b/go/adbc/driver/snowflake/queries/get_objects_terse_catalogs.sql @@ -21,4 +21,4 @@ SELECT 'catalog_name': "name", 'catalog_db_schemas': null } get_objects -FROM TABLE(RESULT_SCAN(:TERSE_QUERY_ID)) +FROM TABLE(RESULT_SCAN(:SHOW_DB_QUERY_ID))