You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ze...@apache.org on 2023/01/24 20:54:21 UTC
[arrow] branch master updated: GH-33852: [Go] Return a catalog/schema from Flight SQL example server (#33853)
This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/master by this push:
new f3637aca77 GH-33852: [Go] Return a catalog/schema from Flight SQL example server (#33853)
f3637aca77 is described below
commit f3637aca7750f43f7e1766e4495254f98adbe40b
Author: David Li <li...@gmail.com>
AuthorDate: Tue Jan 24 15:53:43 2023 -0500
GH-33852: [Go] Return a catalog/schema from Flight SQL example server (#33853)
### Rationale for this change
The example server returns 0 catalogs and 0 schemas because it is based on SQLite. But SQLite does sort of have a concept of catalogs via attached databases. And we should still pretend there is a single (unnamed) schema so that clients get a consistent view of database metadata.
### What changes are included in this PR?
Update how GetTables/GetCatalogs/GetDbSchemas are implemented.
### Are these changes tested?
Tests were updated.
### Are there any user-facing changes?
No, the example is for internal development.
* Closes: #33852
Authored-by: David Li <li...@gmail.com>
Signed-off-by: Matt Topol <zo...@gmail.com>
---
go/arrow/flight/flightsql/example/sqlite_server.go | 49 ++++++++++++++++++----
go/arrow/flight/flightsql/sqlite_server_test.go | 46 ++++++++++++++++----
2 files changed, 78 insertions(+), 17 deletions(-)
diff --git a/go/arrow/flight/flightsql/example/sqlite_server.go b/go/arrow/flight/flightsql/example/sqlite_server.go
index c6b0990312..629818990e 100644
--- a/go/arrow/flight/flightsql/example/sqlite_server.go
+++ b/go/arrow/flight/flightsql/example/sqlite_server.go
@@ -70,7 +70,7 @@ func genRandomString() []byte {
func prepareQueryForGetTables(cmd flightsql.GetTables) string {
var b strings.Builder
- b.WriteString(`SELECT null AS catalog_name, null AS schema_name,
+ b.WriteString(`SELECT 'main' AS catalog_name, '' AS schema_name,
name AS table_name, type AS table_type FROM sqlite_master WHERE 1=1`)
if cmd.GetCatalog() != nil {
@@ -108,7 +108,7 @@ func prepareQueryForGetTables(cmd flightsql.GetTables) string {
func prepareQueryForGetKeys(filter string) string {
return `SELECT * FROM (
- SELECT
+ SELECT
NULL AS pk_catalog_name,
NULL AS pk_schema_name,
p."table" AS pk_table_name,
@@ -162,7 +162,7 @@ func NewSQLiteFlightSQLServer() (*SQLiteFlightSQLServer, error) {
CREATE TABLE foreignTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
foreignName varchar(100),
- value int);
+ value int);
CREATE TABLE intTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -224,10 +224,25 @@ func (s *SQLiteFlightSQLServer) GetFlightInfoCatalogs(_ context.Context, desc *f
}
func (s *SQLiteFlightSQLServer) DoGetCatalogs(context.Context) (*arrow.Schema, <-chan flight.StreamChunk, error) {
- // sqlite doesn't support catalogs, this returns an empty record batch
+ // https://www.sqlite.org/cli.html
+ // > The ".databases" command shows a list of all databases open
+ // > in the current connection. There will always be at least
+ // > 2. The first one is "main", the original database opened. The
+ // > second is "temp", the database used for temporary tables.
+ // For our purposes, return only "main" and ignore other databases.
+
schema := schema_ref.Catalogs
- ch := make(chan flight.StreamChunk)
+ catalogs, _, err := array.FromJSON(s.Alloc, arrow.BinaryTypes.String, strings.NewReader(`["main"]`))
+ if err != nil {
+ return nil, nil, err
+ }
+ defer catalogs.Release()
+
+ batch := array.NewRecord(schema, []arrow.Array{catalogs}, 1)
+
+ ch := make(chan flight.StreamChunk, 1)
+ ch <- flight.StreamChunk{Data: batch}
close(ch)
return schema, ch, nil
@@ -237,11 +252,29 @@ func (s *SQLiteFlightSQLServer) GetFlightInfoSchemas(_ context.Context, cmd flig
return s.flightInfoForCommand(desc, schema_ref.DBSchemas), nil
}
-func (s *SQLiteFlightSQLServer) DoGetDBSchemas(context.Context, flightsql.GetDBSchemas) (*arrow.Schema, <-chan flight.StreamChunk, error) {
- // sqlite doesn't support schemas, this returns an empty record batch
+func (s *SQLiteFlightSQLServer) DoGetDBSchemas(_ context.Context, cmd flightsql.GetDBSchemas) (*arrow.Schema, <-chan flight.StreamChunk, error) {
+ // SQLite doesn't support schemas, so pretend we have a single unnamed schema.
schema := schema_ref.DBSchemas
- ch := make(chan flight.StreamChunk)
+ ch := make(chan flight.StreamChunk, 1)
+
+ if cmd.GetDBSchemaFilterPattern() == nil || *cmd.GetDBSchemaFilterPattern() == "" {
+ catalogs, _, err := array.FromJSON(s.Alloc, arrow.BinaryTypes.String, strings.NewReader(`["main"]`))
+ if err != nil {
+ return nil, nil, err
+ }
+ defer catalogs.Release()
+
+ dbSchemas, _, err := array.FromJSON(s.Alloc, arrow.BinaryTypes.String, strings.NewReader(`[""]`))
+ if err != nil {
+ return nil, nil, err
+ }
+ defer dbSchemas.Release()
+
+ batch := array.NewRecord(schema, []arrow.Array{catalogs, dbSchemas}, 1)
+ ch <- flight.StreamChunk{Data: batch}
+ }
+
close(ch)
return schema, ch, nil
diff --git a/go/arrow/flight/flightsql/sqlite_server_test.go b/go/arrow/flight/flightsql/sqlite_server_test.go
index 1c22e6bf92..a7446fdfef 100644
--- a/go/arrow/flight/flightsql/sqlite_server_test.go
+++ b/go/arrow/flight/flightsql/sqlite_server_test.go
@@ -156,9 +156,9 @@ func (s *FlightSqliteServerSuite) TestCommandGetTables() {
s.NoError(err)
defer rdr.Release()
- catalogName := array.MakeArrayOfNull(s.mem, arrow.BinaryTypes.String, 3)
+ catalogName := s.fromJSON(arrow.BinaryTypes.String, `["main", "main", "main"]`)
defer catalogName.Release()
- schemaName := array.MakeArrayOfNull(s.mem, arrow.BinaryTypes.String, 3)
+ schemaName := s.fromJSON(arrow.BinaryTypes.String, `["", "", ""]`)
defer schemaName.Release()
tableName := s.fromJSON(arrow.BinaryTypes.String, `["foreignTable", "intTable", "sqlite_sequence"]`)
@@ -192,8 +192,8 @@ func (s *FlightSqliteServerSuite) TestCommandGetTablesWithTableFilter() {
s.NoError(err)
defer rdr.Release()
- catalog := s.fromJSON(arrow.BinaryTypes.String, `[null]`)
- schema := s.fromJSON(arrow.BinaryTypes.String, `[null]`)
+ catalog := s.fromJSON(arrow.BinaryTypes.String, `["main"]`)
+ schema := s.fromJSON(arrow.BinaryTypes.String, `[""]`)
table := s.fromJSON(arrow.BinaryTypes.String, `["intTable"]`)
tabletype := s.fromJSON(arrow.BinaryTypes.String, `["table"]`)
expected := array.NewRecord(schema_ref.Tables, []arrow.Array{catalog, schema, table, tabletype}, 1)
@@ -243,9 +243,9 @@ func (s *FlightSqliteServerSuite) TestCommandGetTablesWithExistingTableTypeFilte
s.NoError(err)
defer rdr.Release()
- catalogName := array.MakeArrayOfNull(s.mem, arrow.BinaryTypes.String, 3)
+ catalogName := s.fromJSON(arrow.BinaryTypes.String, `["main", "main", "main"]`)
defer catalogName.Release()
- schemaName := array.MakeArrayOfNull(s.mem, arrow.BinaryTypes.String, 3)
+ schemaName := s.fromJSON(arrow.BinaryTypes.String, `["", "", ""]`)
defer schemaName.Release()
tableName := s.fromJSON(arrow.BinaryTypes.String, `["foreignTable", "intTable", "sqlite_sequence"]`)
@@ -280,8 +280,8 @@ func (s *FlightSqliteServerSuite) TestCommandGetTablesWithIncludedSchemas() {
s.NoError(err)
defer rdr.Release()
- catalog := s.fromJSON(arrow.BinaryTypes.String, `[null]`)
- schema := s.fromJSON(arrow.BinaryTypes.String, `[null]`)
+ catalog := s.fromJSON(arrow.BinaryTypes.String, `["main"]`)
+ schema := s.fromJSON(arrow.BinaryTypes.String, `[""]`)
table := s.fromJSON(arrow.BinaryTypes.String, `["intTable"]`)
tabletype := s.fromJSON(arrow.BinaryTypes.String, `["table"]`)
@@ -367,6 +367,19 @@ func (s *FlightSqliteServerSuite) TestCommandGetCatalogs() {
defer rdr.Release()
s.True(rdr.Schema().Equal(schema_ref.Catalogs), rdr.Schema().String())
+
+ catalog := s.fromJSON(arrow.BinaryTypes.String, `["main"]`)
+ expected := array.NewRecord(schema_ref.Catalogs, []arrow.Array{catalog}, 1)
+ defer catalog.Release()
+ defer expected.Release()
+
+ s.True(rdr.Next())
+ rec := rdr.Record()
+ s.NotNil(rec)
+ rec.Retain()
+ defer rec.Release()
+ s.Truef(array.RecordEqual(expected, rec), "expected: %s\ngot: %s", expected, rec)
+
s.False(rdr.Next())
}
@@ -379,6 +392,21 @@ func (s *FlightSqliteServerSuite) TestCommandGetDbSchemas() {
defer rdr.Release()
s.True(rdr.Schema().Equal(schema_ref.DBSchemas), rdr.Schema().String())
+
+ catalog := s.fromJSON(arrow.BinaryTypes.String, `["main"]`)
+ schema := s.fromJSON(arrow.BinaryTypes.String, `[""]`)
+ expected := array.NewRecord(schema_ref.DBSchemas, []arrow.Array{catalog, schema}, 1)
+ defer catalog.Release()
+ defer schema.Release()
+ defer expected.Release()
+
+ s.True(rdr.Next())
+ rec := rdr.Record()
+ s.NotNil(rec)
+ rec.Retain()
+ defer rec.Release()
+ s.Truef(array.RecordEqual(expected, rec), "expected: %s\ngot: %s", expected, rec)
+
s.False(rdr.Next())
}
@@ -403,7 +431,7 @@ func (s *FlightSqliteServerSuite) TestCommandGetTableTypes() {
func (s *FlightSqliteServerSuite) TestCommandStatementUpdate() {
ctx := context.Background()
- result, err := s.cl.ExecuteUpdate(ctx, `INSERT INTO intTable (keyName, value) VALUES
+ result, err := s.cl.ExecuteUpdate(ctx, `INSERT INTO intTable (keyName, value) VALUES
('KEYNAME1', 1001), ('KEYNAME2', 1002), ('KEYNAME3', 1003)`)
s.NoError(err)
s.EqualValues(3, result)