Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions go/adbc/driver/snowflake/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2005,6 +2005,79 @@ func (suite *SnowflakeTests) TestNonIntDecimalLowPrecision() {
}
}

func (suite *SnowflakeTests) TestSchemaWithLowPrecision() {
// This test verifies that the schema type matches the actual data type
// for NUMBER columns when use_high_precision=false for scale=0 and scale>0
// This is critical for clients that rely on the schema being correct
suite.Require().NoError(suite.Quirks.DropTable(suite.cnxn, "SCHEMA_TYPE_TEST"))

suite.Require().NoError(suite.stmt.SetSqlQuery(`CREATE OR REPLACE TABLE SCHEMA_TYPE_TEST (
INTEGER_COL NUMBER(10,0),
DECIMAL_COL NUMBER(10,2)
)`))
_, err := suite.stmt.ExecuteUpdate(suite.ctx)
suite.Require().NoError(err)

suite.Require().NoError(suite.stmt.SetSqlQuery(`INSERT INTO SCHEMA_TYPE_TEST VALUES
(12345, 123.45),
(67890, 678.90)`))
_, err = suite.stmt.ExecuteUpdate(suite.ctx)
suite.Require().NoError(err)

// Test with use_high_precision=false
suite.Require().NoError(suite.stmt.SetOption(driver.OptionUseHighPrecision, adbc.OptionValueDisabled))
suite.Require().NoError(suite.stmt.SetSqlQuery("SELECT * FROM SCHEMA_TYPE_TEST"))

// First test: ExecuteSchema (schema only, no data)
schemaOnly, err := suite.stmt.(adbc.StatementExecuteSchema).ExecuteSchema(suite.ctx)
suite.Require().NoError(err)

// Verify ExecuteSchema returns correct types
suite.Truef(arrow.TypeEqual(arrow.PrimitiveTypes.Int64, schemaOnly.Field(0).Type),
"ExecuteSchema INTEGER_COL: expected int64, got %s", schemaOnly.Field(0).Type)
suite.Truef(arrow.TypeEqual(arrow.PrimitiveTypes.Float64, schemaOnly.Field(1).Type),
"ExecuteSchema DECIMAL_COL: expected float64, got %s", schemaOnly.Field(1).Type)

// Second test: ExecuteQuery (schema with data)
rdr, n, err := suite.stmt.ExecuteQuery(suite.ctx)
suite.Require().NoError(err)
defer rdr.Release()

suite.EqualValues(2, n)

// Check schema types from ExecuteQuery
schema := rdr.Schema()
suite.Truef(arrow.TypeEqual(arrow.PrimitiveTypes.Int64, schema.Field(0).Type),
"INTEGER_COL: expected int64 in schema, got %s", schema.Field(0).Type)
suite.Truef(arrow.TypeEqual(arrow.PrimitiveTypes.Float64, schema.Field(1).Type),
"DECIMAL_COL: expected float64 in schema, got %s", schema.Field(1).Type)

// Check actual data types in the record
suite.True(rdr.Next())
rec := rdr.Record()

// Verify INTEGER_COL is actually Int64
col0 := rec.Column(0)
suite.Equal(arrow.INT64, col0.DataType().ID(),
"INTEGER_COL data: expected INT64 type, got %s", col0.DataType())
suite.Equal(int64(12345), col0.(*array.Int64).Value(0))

// Verify DECIMAL_COL is actually Float64
col1 := rec.Column(1)
suite.Equal(arrow.FLOAT64, col1.DataType().ID(),
"DECIMAL_COL data: expected FLOAT64 type, got %s", col1.DataType())
suite.InDelta(123.45, col1.(*array.Float64).Value(0), 0.001)

// Check second row
suite.Equal(int64(67890), col0.(*array.Int64).Value(1))
suite.InDelta(678.90, col1.(*array.Float64).Value(1), 0.001)

// Verify schema type matches actual data type
suite.Equal(schema.Field(1).Type.ID(), col1.DataType().ID(),
"Schema type must match data type for DECIMAL_COL: schema says %s, data is %s",
schema.Field(1).Type, col1.DataType())
}

func (suite *SnowflakeTests) TestIntDecimalLowPrecision() {
for sign := 0; sign <= 1; sign++ {
for precision := 3; precision <= 38; precision++ {
Expand Down
7 changes: 6 additions & 1 deletion go/adbc/driver/snowflake/record_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,12 @@ func rowTypesToArrowSchema(_ context.Context, ld gosnowflake.ArrowStreamLoader,
Scale: int32(srcMeta.Scale),
}
} else {
fields[i].Type = arrow.PrimitiveTypes.Int64
// Check scale to determine if this is an integer or decimal
if srcMeta.Scale == 0 {
fields[i].Type = arrow.PrimitiveTypes.Int64
} else {
fields[i].Type = arrow.PrimitiveTypes.Float64
}
}
case "real":
fields[i].Type = arrow.PrimitiveTypes.Float64
Expand Down
Loading