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
+
+ })
+ }
+}