This is an automated email from the ASF dual-hosted git repository.

zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git


The following commit(s) were added to refs/heads/main by this push:
     new e20202bd feat(go/adbc/driver/snowflake): improve XDBC support (#1034)
e20202bd is described below

commit e20202bdd115f24e4eba57d4d873aa360ff10e4e
Author: davidhcoe <[email protected]>
AuthorDate: Thu Sep 14 11:25:45 2023 -0400

    feat(go/adbc/driver/snowflake): improve XDBC support (#1034)
    
    Enhance XDBC values for Snowflake
    
    ---------
    
    Co-authored-by: David Coe <[email protected]>
---
 go/adbc/driver/internal/shared_utils.go | 132 ++++++++++++++++++++--
 go/adbc/driver/snowflake/connection.go  | 107 ++++++++++++++++--
 go/adbc/driver/snowflake/driver_test.go | 191 ++++++++++++++++++++++++++++++++
 3 files changed, 411 insertions(+), 19 deletions(-)

diff --git a/go/adbc/driver/internal/shared_utils.go 
b/go/adbc/driver/internal/shared_utils.go
index 92a8a8e4..1b197e6f 100644
--- a/go/adbc/driver/internal/shared_utils.go
+++ b/go/adbc/driver/internal/shared_utils.go
@@ -267,6 +267,17 @@ func (g *GetObjects) appendTableInfo(tableInfo TableInfo) {
                if !column.HasMetadata() {
                        g.ordinalPositionBuilder.Append(int32(colIndex + 1))
                        g.remarksBuilder.AppendNull()
+
+                       g.xdbcDataTypeBuilder.AppendNull()
+                       g.xdbcTypeNameBuilder.AppendNull()
+                       g.xdbcNullableBuilder.AppendNull()
+                       g.xdbcIsNullableBuilder.AppendNull()
+                       g.xdbcColumnSizeBuilder.AppendNull()
+                       g.xdbcDecimalDigitsBuilder.AppendNull()
+                       g.xdbcNumPrecRadixBuilder.AppendNull()
+                       g.xdbcCharOctetLengthBuilder.AppendNull()
+                       g.xdbcDatetimeSubBuilder.AppendNull()
+                       g.xdbcSqlDataTypeBuilder.AppendNull()
                } else {
                        if remark, ok := column.Metadata.GetValue("COMMENT"); 
ok {
                                g.remarksBuilder.Append(remark)
@@ -274,7 +285,80 @@ func (g *GetObjects) appendTableInfo(tableInfo TableInfo) {
                                g.remarksBuilder.AppendNull()
                        }
 
+                       if typeName, ok := 
column.Metadata.GetValue("XDBC_TYPE_NAME"); ok {
+                               g.xdbcTypeNameBuilder.Append(typeName)
+                       } else {
+                               g.xdbcTypeNameBuilder.AppendNull()
+                       }
+
+                       if strNullable, ok := 
column.Metadata.GetValue("XDBC_NULLABLE"); ok {
+                               nullable, _ := strconv.ParseBool(strNullable)
+                               
g.xdbcNullableBuilder.Append(boolToInt16(nullable))
+                       } else {
+                               g.xdbcNullableBuilder.AppendNull()
+                       }
+
+                       if strIsNullable, ok := 
column.Metadata.GetValue("XDBC_IS_NULLABLE"); ok {
+                               g.xdbcIsNullableBuilder.Append(strIsNullable)
+                       } else {
+                               g.xdbcIsNullableBuilder.AppendNull()
+                       }
+
+                       if strDataTypeId, ok := 
column.Metadata.GetValue("XDBC_DATA_TYPE"); ok {
+                               dataTypeId64, _ := 
strconv.ParseInt(strDataTypeId, 10, 16)
+                               
g.xdbcDataTypeBuilder.Append(int16(dataTypeId64))
+
+                       } else {
+                               g.xdbcDataTypeBuilder.AppendNull()
+                       }
+
+                       if strSqlDataTypeId, ok := 
column.Metadata.GetValue("XDBC_SQL_DATA_TYPE"); ok {
+                               sqlDataTypeId64, _ := 
strconv.ParseInt(strSqlDataTypeId, 10, 16)
+                               
g.xdbcSqlDataTypeBuilder.Append(int16(sqlDataTypeId64))
+                       } else {
+                               g.xdbcSqlDataTypeBuilder.AppendNull()
+                       }
+
+                       if strPrecision, ok := 
column.Metadata.GetValue("XDBC_PRECISION"); ok { // for numeric values
+                               precision64, _ := 
strconv.ParseInt(strPrecision, 10, 32)
+                               
g.xdbcColumnSizeBuilder.Append(int32(precision64))
+                       } else if strCharLimit, ok := 
column.Metadata.GetValue("CHARACTER_MAXIMUM_LENGTH"); ok { // for text values
+                               charLimit64, _ := 
strconv.ParseInt(strCharLimit, 10, 32)
+                               
g.xdbcColumnSizeBuilder.Append(int32(charLimit64))
+                       } else {
+                               g.xdbcColumnSizeBuilder.AppendNull()
+                       }
+
+                       if strScale, ok := 
column.Metadata.GetValue("XDBC_SCALE"); ok {
+                               scale64, _ := strconv.ParseInt(strScale, 10, 16)
+                               
g.xdbcDecimalDigitsBuilder.Append(int16(scale64))
+                       } else {
+                               g.xdbcDecimalDigitsBuilder.AppendNull()
+                       }
+
+                       if strPrecRadix, ok := 
column.Metadata.GetValue("XDBC_NUM_PREC_RADIX"); ok {
+                               precRadix64, _ := 
strconv.ParseInt(strPrecRadix, 10, 16)
+                               
g.xdbcNumPrecRadixBuilder.Append(int16(precRadix64))
+                       } else {
+                               g.xdbcNumPrecRadixBuilder.AppendNull()
+                       }
+
+                       if strCharOctetLen, ok := 
column.Metadata.GetValue("XDBC_CHAR_OCTET_LENGTH"); ok {
+                               charOctLen64, _ := 
strconv.ParseInt(strCharOctetLen, 10, 32)
+                               
g.xdbcCharOctetLengthBuilder.Append(int32(charOctLen64))
+                       } else {
+                               g.xdbcCharOctetLengthBuilder.AppendNull()
+                       }
+
+                       if strDateTimeSub, ok := 
column.Metadata.GetValue("XDBC_DATETIME_SUB"); ok {
+                               dateTimeSub64, _ := 
strconv.ParseInt(strDateTimeSub, 10, 16)
+                               
g.xdbcDatetimeSubBuilder.Append(int16(dateTimeSub64))
+                       } else {
+                               g.xdbcDatetimeSubBuilder.AppendNull()
+                       }
+
                        pos := int32(colIndex + 1)
+
                        if ordinal, ok := 
column.Metadata.GetValue("ORDINAL_POSITION"); ok {
                                v, err := strconv.ParseInt(ordinal, 10, 32)
                                if err == nil {
@@ -284,17 +368,7 @@ func (g *GetObjects) appendTableInfo(tableInfo TableInfo) {
                        g.ordinalPositionBuilder.Append(pos)
                }
 
-               g.xdbcDataTypeBuilder.AppendNull()
-               g.xdbcTypeNameBuilder.AppendNull()
-               g.xdbcColumnSizeBuilder.AppendNull()
-               g.xdbcDecimalDigitsBuilder.AppendNull()
-               g.xdbcNumPrecRadixBuilder.AppendNull()
-               g.xdbcNullableBuilder.AppendNull()
                g.xdbcColumnDefBuilder.AppendNull()
-               g.xdbcSqlDataTypeBuilder.AppendNull()
-               g.xdbcDatetimeSubBuilder.AppendNull()
-               g.xdbcCharOctetLengthBuilder.AppendNull()
-               g.xdbcIsNullableBuilder.AppendNull()
                g.xdbcScopeCatalogBuilder.AppendNull()
                g.xdbcScopeSchemaBuilder.AppendNull()
                g.xdbcScopeTableBuilder.AppendNull()
@@ -304,3 +378,41 @@ func (g *GetObjects) appendTableInfo(tableInfo TableInfo) {
                g.tableColumnsItems.Append(true)
        }
 }
+
+func boolToInt16(b bool) int16 {
+       if b {
+               return 1
+       }
+       return 0
+}
+
+// The JDBC/ODBC-defined type of any object.
+// All the values here are the sames as in the JDBC and ODBC specs.
+type XdbcDataType int32
+
+const (
+       XdbcDataType_XDBC_UNKNOWN_TYPE  XdbcDataType = 0
+       XdbcDataType_XDBC_CHAR          XdbcDataType = 1
+       XdbcDataType_XDBC_NUMERIC       XdbcDataType = 2
+       XdbcDataType_XDBC_DECIMAL       XdbcDataType = 3
+       XdbcDataType_XDBC_INTEGER       XdbcDataType = 4
+       XdbcDataType_XDBC_SMALLINT      XdbcDataType = 5
+       XdbcDataType_XDBC_FLOAT         XdbcDataType = 6
+       XdbcDataType_XDBC_REAL          XdbcDataType = 7
+       XdbcDataType_XDBC_DOUBLE        XdbcDataType = 8
+       XdbcDataType_XDBC_DATETIME      XdbcDataType = 9
+       XdbcDataType_XDBC_INTERVAL      XdbcDataType = 10
+       XdbcDataType_XDBC_VARCHAR       XdbcDataType = 12
+       XdbcDataType_XDBC_DATE          XdbcDataType = 91
+       XdbcDataType_XDBC_TIME          XdbcDataType = 92
+       XdbcDataType_XDBC_TIMESTAMP     XdbcDataType = 93
+       XdbcDataType_XDBC_LONGVARCHAR   XdbcDataType = -1
+       XdbcDataType_XDBC_BINARY        XdbcDataType = -2
+       XdbcDataType_XDBC_VARBINARY     XdbcDataType = -3
+       XdbcDataType_XDBC_LONGVARBINARY XdbcDataType = -4
+       XdbcDataType_XDBC_BIGINT        XdbcDataType = -5
+       XdbcDataType_XDBC_TINYINT       XdbcDataType = -6
+       XdbcDataType_XDBC_BIT           XdbcDataType = -7
+       XdbcDataType_XDBC_WCHAR         XdbcDataType = -8
+       XdbcDataType_XDBC_WVARCHAR      XdbcDataType = -9
+)
diff --git a/go/adbc/driver/snowflake/connection.go 
b/go/adbc/driver/snowflake/connection.go
index 628ac85f..c8f1dc75 100644
--- a/go/adbc/driver/snowflake/connection.go
+++ b/go/adbc/driver/snowflake/connection.go
@@ -362,8 +362,9 @@ func (c *cnxn) getObjectsDbSchemas(ctx context.Context, 
depth adbc.ObjectDepth,
 
 var loc = time.Now().Location()
 
-func toField(name string, isnullable bool, dataType string, numPrec, 
numPrecRadix, numScale sql.NullInt16, isIdent bool, identGen, identInc, comment 
sql.NullString, ordinalPos int) (ret arrow.Field) {
+func toField(name string, isnullable bool, dataType string, numPrec, 
numPrecRadix, numScale sql.NullInt16, isIdent bool, identGen, identInc 
sql.NullString, charMaxLength, charOctetLength sql.NullInt32, datetimePrec 
sql.NullInt16, comment sql.NullString, ordinalPos int) (ret arrow.Field) {
        ret.Name, ret.Nullable = name, isnullable
+
        switch dataType {
        case "NUMBER":
                if !numScale.Valid || numScale.Int16 == 0 {
@@ -416,12 +417,98 @@ func toField(name string, isnullable bool, dataType 
string, numPrec, numPrecRadi
        if comment.Valid {
                md["COMMENT"] = comment.String
        }
+
        md["ORDINAL_POSITION"] = strconv.Itoa(ordinalPos)
+       md["XDBC_DATA_TYPE"] = strconv.Itoa(int(ret.Type.ID()))
+       md["XDBC_TYPE_NAME"] = dataType
+       md["XDBC_SQL_DATA_TYPE"] = strconv.Itoa(int(toXdbcDataType(ret.Type)))
+       md["XDBC_NULLABLE"] = strconv.FormatBool(isnullable)
+
+       if isnullable {
+               md["XDBC_IS_NULLABLE"] = "YES"
+       } else {
+               md["XDBC_IS_NULLABLE"] = "NO"
+       }
+
+       if numPrec.Valid {
+               md["XDBC_PRECISION"] = strconv.Itoa(int(numPrec.Int16))
+       }
+
+       if numScale.Valid {
+               md["XDBC_SCALE"] = strconv.Itoa(int(numScale.Int16))
+       }
+
+       if numPrec.Valid {
+               md["XDBC_PRECISION"] = strconv.Itoa(int(numPrec.Int16))
+       }
+
+       if numPrecRadix.Valid {
+               md["XDBC_NUM_PREC_RADIX"] = 
strconv.Itoa(int(numPrecRadix.Int16))
+       }
+
+       if charMaxLength.Valid {
+               md["CHARACTER_MAXIMUM_LENGTH"] = 
strconv.Itoa(int(charMaxLength.Int32))
+       }
+
+       if charOctetLength.Valid {
+               md["XDBC_CHAR_OCTET_LENGTH"] = 
strconv.Itoa(int(charOctetLength.Int32))
+       }
+
+       if datetimePrec.Valid {
+               md["XDBC_DATETIME_SUB"] = strconv.Itoa(int(datetimePrec.Int16))
+       }
 
        ret.Metadata = arrow.MetadataFrom(md)
+
        return
 }
 
+func toXdbcDataType(dt arrow.DataType) (xdbcType internal.XdbcDataType) {
+       xdbcType = internal.XdbcDataType_XDBC_UNKNOWN_TYPE
+       switch dt.ID() {
+       case arrow.EXTENSION:
+               return toXdbcDataType(dt.(arrow.ExtensionType).StorageType())
+       case arrow.DICTIONARY:
+               return toXdbcDataType(dt.(*arrow.DictionaryType).ValueType)
+       case arrow.RUN_END_ENCODED:
+               return toXdbcDataType(dt.(*arrow.RunEndEncodedType).Encoded())
+       case arrow.INT8, arrow.UINT8:
+               return internal.XdbcDataType_XDBC_TINYINT
+       case arrow.INT16, arrow.UINT16:
+               return internal.XdbcDataType_XDBC_SMALLINT
+       case arrow.INT32, arrow.UINT32:
+               return internal.XdbcDataType_XDBC_SMALLINT
+       case arrow.INT64, arrow.UINT64:
+               return internal.XdbcDataType_XDBC_BIGINT
+       case arrow.FLOAT32, arrow.FLOAT16, arrow.FLOAT64:
+               return internal.XdbcDataType_XDBC_FLOAT
+       case arrow.DECIMAL, arrow.DECIMAL256:
+               return internal.XdbcDataType_XDBC_DECIMAL
+       case arrow.STRING, arrow.LARGE_STRING:
+               return internal.XdbcDataType_XDBC_VARCHAR
+       case arrow.BINARY, arrow.LARGE_BINARY:
+               return internal.XdbcDataType_XDBC_BINARY
+       case arrow.FIXED_SIZE_BINARY:
+               return internal.XdbcDataType_XDBC_BINARY
+       case arrow.BOOL:
+               return internal.XdbcDataType_XDBC_BIT
+       case arrow.TIME32, arrow.TIME64:
+               return internal.XdbcDataType_XDBC_TIME
+       case arrow.DATE32, arrow.DATE64:
+               return internal.XdbcDataType_XDBC_DATE
+       case arrow.TIMESTAMP:
+               return internal.XdbcDataType_XDBC_TIMESTAMP
+       case arrow.DENSE_UNION, arrow.SPARSE_UNION:
+               return internal.XdbcDataType_XDBC_VARBINARY
+       case arrow.LIST, arrow.LARGE_LIST, arrow.FIXED_SIZE_LIST:
+               return internal.XdbcDataType_XDBC_VARBINARY
+       case arrow.STRUCT, arrow.MAP:
+               return internal.XdbcDataType_XDBC_VARBINARY
+       default:
+               return internal.XdbcDataType_XDBC_UNKNOWN_TYPE
+       }
+}
+
 func (c *cnxn) getObjectsTables(ctx context.Context, depth adbc.ObjectDepth, 
catalog *string, dbSchema *string, tableName *string, columnName *string, 
tableType []string) (result internal.SchemaToTableInfo, err error) {
        if depth == adbc.ObjectDepthCatalogs || depth == 
adbc.ObjectDepthDBSchemas {
                return
@@ -484,7 +571,8 @@ func (c *cnxn) getObjectsTables(ctx context.Context, depth 
adbc.ObjectDepth, cat
                                table_catalog, table_schema, table_name, 
column_name,
                                ordinal_position, is_nullable::boolean, 
data_type, numeric_precision,
                                numeric_precision_radix, numeric_scale, 
is_identity::boolean,
-                               identity_generation, identity_increment, comment
+                               identity_generation, identity_increment,
+                               character_maximum_length, 
character_octet_length, datetime_precision, comment
                FROM ' || rec.database_name || '.INFORMATION_SCHEMA.COLUMNS';
 
                  counter := counter + 1;
@@ -552,11 +640,12 @@ func (c *cnxn) getObjectsTables(ctx context.Context, 
depth adbc.ObjectDepth, cat
                defer rows.Close()
 
                var (
-                       colName, dataType                           string
-                       identGen, identIncrement, comment           
sql.NullString
-                       ordinalPos                                  int
-                       numericPrec, numericPrecRadix, numericScale 
sql.NullInt16
-                       isNullable, isIdent                         bool
+                       colName, dataType                                       
  string
+                       identGen, identIncrement, comment                       
  sql.NullString
+                       ordinalPos                                              
  int
+                       numericPrec, numericPrecRadix, numericScale, 
datetimePrec sql.NullInt16
+                       isNullable, isIdent                                     
  bool
+                       charMaxLength, charOctetLength                          
  sql.NullInt32
 
                        prevKey      internal.CatalogAndSchema
                        curTableInfo *internal.TableInfo
@@ -568,7 +657,7 @@ func (c *cnxn) getObjectsTables(ctx context.Context, depth 
adbc.ObjectDepth, cat
                        err = rows.Scan(&tblCat, &tblSchema, &tblName, &colName,
                                &ordinalPos, &isNullable, &dataType, 
&numericPrec,
                                &numericPrecRadix, &numericScale, &isIdent, 
&identGen,
-                               &identIncrement, &comment)
+                               &identIncrement, &charMaxLength, 
&charOctetLength, &datetimePrec, &comment)
                        if err != nil {
                                err = errToAdbcErr(adbc.StatusIO, err)
                                return
@@ -591,7 +680,7 @@ func (c *cnxn) getObjectsTables(ctx context.Context, depth 
adbc.ObjectDepth, cat
                        }
 
                        prevKey = key
-                       fieldList = append(fieldList, toField(colName, 
isNullable, dataType, numericPrec, numericPrecRadix, numericScale, isIdent, 
identGen, identIncrement, comment, ordinalPos))
+                       fieldList = append(fieldList, toField(colName, 
isNullable, dataType, numericPrec, numericPrecRadix, numericScale, isIdent, 
identGen, identIncrement, charMaxLength, charOctetLength, datetimePrec, 
comment, ordinalPos))
                }
 
                if len(fieldList) > 0 && curTableInfo != nil {
diff --git a/go/adbc/driver/snowflake/driver_test.go 
b/go/adbc/driver/snowflake/driver_test.go
index 89fc566d..204cc983 100644
--- a/go/adbc/driver/snowflake/driver_test.go
+++ b/go/adbc/driver/snowflake/driver_test.go
@@ -22,10 +22,12 @@ import (
        "database/sql"
        "fmt"
        "os"
+       "strconv"
        "strings"
        "testing"
 
        "github.com/apache/arrow-adbc/go/adbc"
+       "github.com/apache/arrow-adbc/go/adbc/driver/internal"
        driver "github.com/apache/arrow-adbc/go/adbc/driver/snowflake"
        "github.com/apache/arrow-adbc/go/adbc/validation"
        "github.com/apache/arrow/go/v13/arrow"
@@ -393,3 +395,192 @@ func (suite *SnowflakeTests) 
TestStatementEmptyResultSet() {
        suite.False(rdr.Next())
        suite.NoError(rdr.Err())
 }
+
+func (suite *SnowflakeTests) TestMetadataGetObjectsColumnsXdbc() {
+
+       suite.Require().NoError(suite.Quirks.DropTable(suite.cnxn, 
"bulk_ingest"))
+
+       mdInts := make(map[string]string)
+       mdInts["TYPE_NAME"] = "NUMERIC"
+       mdInts["ORDINAL_POSITION"] = "1"
+       mdInts["XDBC_DATA_TYPE"] = 
strconv.Itoa(int(arrow.PrimitiveTypes.Int64.ID()))
+       mdInts["XDBC_TYPE_NAME"] = "NUMERIC"
+       mdInts["XDBC_SQL_DATA_TYPE"] = 
strconv.Itoa(int(internal.XdbcDataType_XDBC_BIGINT))
+       mdInts["XDBC_NULLABLE"] = strconv.FormatBool(true)
+       mdInts["XDBC_IS_NULLABLE"] = "YES"
+       mdInts["XDBC_PRECISION"] = strconv.Itoa(38)
+       mdInts["XDBC_SCALE"] = strconv.Itoa(0)
+       mdInts["XDBC_NUM_PREC_RADIX"] = strconv.Itoa(10)
+
+       mdStrings := make(map[string]string)
+       mdStrings["TYPE_NAME"] = "TEXT"
+       mdStrings["ORDINAL_POSITION"] = "2"
+       mdStrings["XDBC_DATA_TYPE"] = 
strconv.Itoa(int(arrow.BinaryTypes.String.ID()))
+       mdStrings["XDBC_TYPE_NAME"] = "TEXT"
+       mdStrings["XDBC_SQL_DATA_TYPE"] = 
strconv.Itoa(int(internal.XdbcDataType_XDBC_VARCHAR))
+       mdStrings["XDBC_IS_NULLABLE"] = "YES"
+       mdStrings["CHARACTER_MAXIMUM_LENGTH"] = strconv.Itoa(16777216)
+       mdStrings["XDBC_CHAR_OCTET_LENGTH"] = strconv.Itoa(16777216)
+
+       rec, _, err := array.RecordFromJSON(suite.Quirks.Alloc(), 
arrow.NewSchema(
+               []arrow.Field{
+                       {Name: "int64s", Type: arrow.PrimitiveTypes.Int64, 
Nullable: true, Metadata: arrow.MetadataFrom(mdInts)},
+                       {Name: "strings", Type: arrow.BinaryTypes.String, 
Nullable: true, Metadata: arrow.MetadataFrom(mdStrings)},
+               }, nil), strings.NewReader(`[
+                       {"int64s": 42, "strings": "foo"},
+                       {"int64s": -42, "strings": null},
+                       {"int64s": null, "strings": ""}
+               ]`))
+       suite.Require().NoError(err)
+       defer rec.Release()
+
+       suite.Require().NoError(suite.Quirks.CreateSampleTable("bulk_ingest", 
rec))
+
+       tests := []struct {
+               name             string
+               colnames         []string
+               positions        []string
+               dataTypes        []string
+               comments         []string
+               xdbcDataType     []string
+               xdbcTypeName     []string
+               xdbcSqlDataType  []string
+               xdbcNullable     []string
+               xdbcIsNullable   []string
+               xdbcScale        []string
+               xdbcNumPrecRadix []string
+               xdbcCharMaxLen   []string
+               xdbcCharOctetLen []string
+               xdbcDateTimeSub  []string
+       }{
+               {
+                       "BASIC",                       //name
+                       []string{"int64s", "strings"}, //colNames
+                       []string{"1", "2"},            //positions
+                       []string{"NUMBER", "TEXT"},    //dataTypes
+                       []string{"", ""},              //comments
+                       []string{"9", "13"},           //xdbcDataType
+                       []string{"NUMBER", "TEXT"},    //xdbcTypeName
+                       []string{"-5", "12"},          //xdbcSqlDataType
+                       []string{"1", "1"},            //xdbcNullable
+                       []string{"YES", "YES"},        //xdbcIsNullable
+                       []string{"0", "0"},            //xdbcScale
+                       []string{"10", "0"},           //xdbcNumPrecRadix
+                       []string{"38", "16777216"},    //xdbcCharMaxLen 
(xdbcPrecision)
+                       []string{"0", "16777216"},     //xdbcCharOctetLen
+                       []string{"-5", "12", "0"},     //xdbcDateTimeSub
+               },
+       }
+
+       for _, tt := range tests {
+               suite.Run(tt.name, func() {
+                       rdr, err := suite.cnxn.GetObjects(suite.ctx, 
adbc.ObjectDepthColumns, nil, nil, nil, nil, nil)
+                       suite.Require().NoError(err)
+                       defer rdr.Release()
+
+                       suite.Truef(adbc.GetObjectsSchema.Equal(rdr.Schema()), 
"expected: %s\ngot: %s", adbc.GetObjectsSchema, rdr.Schema())
+                       suite.True(rdr.Next())
+                       rec := rdr.Record()
+                       suite.Greater(rec.NumRows(), int64(0))
+                       var (
+                               foundExpected        = false
+                               catalogDbSchemasList = 
rec.Column(1).(*array.List)
+                               catalogDbSchemas     = 
catalogDbSchemasList.ListValues().(*array.Struct)
+                               dbSchemaNames        = 
catalogDbSchemas.Field(0).(*array.String)
+                               dbSchemaTablesList   = 
catalogDbSchemas.Field(1).(*array.List)
+                               dbSchemaTables       = 
dbSchemaTablesList.ListValues().(*array.Struct)
+                               tableColumnsList     = 
dbSchemaTables.Field(2).(*array.List)
+                               tableColumns         = 
tableColumnsList.ListValues().(*array.Struct)
+
+                               colnames          = make([]string, 0)
+                               positions         = make([]string, 0)
+                               comments          = make([]string, 0)
+                               xdbcDataTypes     = make([]string, 0)
+                               dataTypes         = make([]string, 0)
+                               xdbcTypeNames     = make([]string, 0)
+                               xdbcCharMaxLens   = make([]string, 0)
+                               xdbcScales        = make([]string, 0)
+                               xdbcNumPrecRadixs = make([]string, 0)
+                               xdbcNullables     = make([]string, 0)
+                               xdbcSqlDataTypes  = make([]string, 0)
+                               xdbcDateTimeSub   = make([]string, 0)
+                               xdbcCharOctetLen  = make([]string, 0)
+                               xdbcIsNullables   = make([]string, 0)
+                       )
+                       for row := 0; row < int(rec.NumRows()); row++ {
+                               dbSchemaIdxStart, dbSchemaIdxEnd := 
catalogDbSchemasList.ValueOffsets(row)
+                               for dbSchemaIdx := dbSchemaIdxStart; 
dbSchemaIdx < dbSchemaIdxEnd; dbSchemaIdx++ {
+                                       schemaName := 
dbSchemaNames.Value(int(dbSchemaIdx))
+                                       tblIdxStart, tblIdxEnd := 
dbSchemaTablesList.ValueOffsets(int(dbSchemaIdx))
+                                       for tblIdx := tblIdxStart; tblIdx < 
tblIdxEnd; tblIdx++ {
+                                               tableName := 
dbSchemaTables.Field(0).(*array.String).Value(int(tblIdx))
+
+                                               if 
strings.EqualFold(schemaName, suite.Quirks.DBSchema()) && 
strings.EqualFold("bulk_ingest", tableName) {
+                                                       foundExpected = true
+
+                                                       colIdxStart, colIdxEnd 
:= tableColumnsList.ValueOffsets(int(tblIdx))
+                                                       for colIdx := 
colIdxStart; colIdx < colIdxEnd; colIdx++ {
+                                                               name := 
tableColumns.Field(0).(*array.String).Value(int(colIdx))
+                                                               colnames = 
append(colnames, strings.ToLower(name))
+
+                                                               pos := 
tableColumns.Field(1).(*array.Int32).Value(int(colIdx))
+                                                               positions = 
append(positions, strconv.Itoa(int(pos)))
+
+                                                               comments = 
append(comments, tableColumns.Field(2).(*array.String).Value(int(colIdx)))
+
+                                                               xdt := 
tableColumns.Field(3).(*array.Int16).Value(int(colIdx))
+                                                               xdbcDataTypes = 
append(xdbcDataTypes, strconv.Itoa(int(xdt)))
+
+                                                               dataType := 
tableColumns.Field(4).(*array.String).Value(int(colIdx))
+                                                               dataTypes = 
append(dataTypes, dataType)
+                                                               xdbcTypeNames = 
append(xdbcTypeNames, dataType)
+
+                                                               // these are 
column size attributes used for either precision for numbers OR the length for 
text
+                                                               
maxLenOrPrecision := tableColumns.Field(5).(*array.Int32).Value(int(colIdx))
+                                                               xdbcCharMaxLens 
= append(xdbcCharMaxLens, strconv.Itoa(int(maxLenOrPrecision)))
+
+                                                               scale := 
tableColumns.Field(6).(*array.Int16).Value(int(colIdx))
+                                                               xdbcScales = 
append(xdbcScales, strconv.Itoa(int(scale)))
+
+                                                               radix := 
tableColumns.Field(7).(*array.Int16).Value(int(colIdx))
+                                                               
xdbcNumPrecRadixs = append(xdbcNumPrecRadixs, strconv.Itoa(int(radix)))
+
+                                                               isnull := 
tableColumns.Field(8).(*array.Int16).Value(int(colIdx))
+                                                               xdbcNullables = 
append(xdbcNullables, strconv.Itoa(int(isnull)))
+
+                                                               sqlType := 
tableColumns.Field(10).(*array.Int16).Value(int(colIdx))
+                                                               
xdbcSqlDataTypes = append(xdbcSqlDataTypes, strconv.Itoa(int(sqlType)))
+
+                                                               dtPrec := 
tableColumns.Field(11).(*array.Int16).Value(int(colIdx))
+                                                               xdbcDateTimeSub 
= append(xdbcSqlDataTypes, strconv.Itoa(int(dtPrec)))
+
+                                                               charOctetLen := 
tableColumns.Field(12).(*array.Int32).Value(int(colIdx))
+                                                               
xdbcCharOctetLen = append(xdbcCharOctetLen, strconv.Itoa(int(charOctetLen)))
+
+                                                               xdbcIsNullables 
= append(xdbcIsNullables, 
tableColumns.Field(13).(*array.String).Value(int(colIdx)))
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+                       suite.False(rdr.Next())
+                       suite.True(foundExpected)
+                       suite.Equal(tt.colnames, colnames)                  
//colNames
+                       suite.Equal(tt.positions, positions)                
//positions
+                       suite.Equal(tt.comments, comments)                  
//comments
+                       suite.Equal(tt.xdbcDataType, xdbcDataTypes)         
//xdbcDataType
+                       suite.Equal(tt.dataTypes, dataTypes)                
//dataTypes
+                       suite.Equal(tt.xdbcTypeName, xdbcTypeNames)         
//xdbcTypeName
+                       suite.Equal(tt.xdbcCharMaxLen, xdbcCharMaxLens)     
//xdbcCharMaxLen
+                       suite.Equal(tt.xdbcScale, xdbcScales)               
//xdbcScale
+                       suite.Equal(tt.xdbcNumPrecRadix, xdbcNumPrecRadixs) 
//xdbcNumPrecRadix
+                       suite.Equal(tt.xdbcNullable, xdbcNullables)         
//xdbcNullable
+                       suite.Equal(tt.xdbcSqlDataType, xdbcSqlDataTypes)   
//xdbcSqlDataType
+                       suite.Equal(tt.xdbcDateTimeSub, xdbcDateTimeSub)    
//xdbcDateTimeSub
+                       suite.Equal(tt.xdbcCharOctetLen, xdbcCharOctetLen)  
//xdbcCharOctetLen
+                       suite.Equal(tt.xdbcIsNullable, xdbcIsNullables)     
//xdbcIsNullable
+
+               })
+       }
+}

Reply via email to