Error while scanning column of type `array<decimal(10,2)>` into Go type `[]float64`
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
调研方向
运行报告中的 Test_Float64_Conversion 复现,然后阅读 internal/rows/arrowbased/columnValues.go 中 listValueContainer.Value 附近的代码;该位置已被确定为字符串值的来源。将 array<decimal(10,2)> 列扫描到 []float64 时能够成功,且不再出现报告的 database/sql 转换错误,即表示完成。
由索引模型根据 Issue 内容生成。
描述
I have a table that has a column AMOUNTS with a type array<decimal(10,2)>, which I expect to scan into a field type []float64.
This is the test I wrote to reproduce it:
func (s *DatabricksRepositorySuite) Test_Float64_Conversion() {
query := `SELECT AMOUNTS FROM components WHERE AMOUNTS IS NOT NULL AND array_size(AMOUNTS) > 0 LIMIT 1`
var result []float64
err := s.repository.db.QueryRow(query).Scan(&result)
s.NoError(err)
}
When I run my query, I get this error:
sql: Scan error on column index 0, name "AMOUNTS": unsupported Scan, storing driver.Value type string into type *[]float64
Source
This error comes from the standard library in Go: the value for that field is provided by the SDK as a string, but the destination is []float64, so it fails. I also dove into Databricks' SDK source code and found the place [2] where the string is generated.
[1] Golang source - convertAssignRows
[2] Databricks SDK - listValueContainer.Value
Workaround
I created a custom type for the fields I have that use arrays:
import (
"database/sql/driver"
"encoding/json"
"errors"
)
type databricksArray[T any] struct {
parsedValue []T
}
func (f *databricksArray[T]) Scan(value interface{}) error {
switch typedValue := value.(type) {
case []T:
f.parsedValue = typedValue
return nil
case string:
return f.parseString(typedValue)
default:
return errors.New("error while handling databricks type")
}
}
func (f *databricksArray[T]) parseString(value string) error {
// This is a workaround for Databricks returning float arrays as strings
// Example: `[1.0, 2.0, 3.0]`
// We need to convert it to an array
// This should be removed if/when Databricks fixes this issue
valueBytes := []byte(value)
var parsedValue []T
if err := json.Unmarshal(valueBytes, &parsedValue); err != nil {
return err
}
f.parsedValue = parsedValue
return nil
}
func (f *databricksArray[T]) Value() (driver.Value, error) {
return f.parsedValue, nil
}
func (f *databricksArray[T]) Slice() []T {
if f == nil {
return nil
}
return f.parsedValue
}
So my field
Amount []float64 `db:"AMOUNTS"`
is now
Amount databricksArray[float64] `db:"AMOUNTS"`
and I call Amount.Slice() when I want to read its value.
- 主要语言
- Go
- 星标
- 53
- 派生
- 68
- 平均合并
- 2 天 1 小时
- 30 天内合并 PR
- 8
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
databricks/databricks-sql-go 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 70/100
databricks/databricks-sql-go#494 ·
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 48/100
databricks/databricks-sql-go#499 ·
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 64/100
databricks/databricks-sql-go#490 ·
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 55/100
databricks/databricks-sql-go#481 ·
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 52/100
databricks/databricks-sql-go#480 ·
维护者通常 1 天内回复
查看 databricks/databricks-sql-go 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 75/100
维护者通常 1 天内回复
-
ViewData can pair the in-flight proposal with the prepared flag of another proposal可能已有人在做 @HagarMeir 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 82/100
hyperledger/SmartBFT#710 ·
维护者通常 1 天内回复
-
agent-butler-finding chore
难度 1/5 1 小时以内 新手友好度 90/100
jordansmall/spindrift#5575 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 88/100
open-telemetry/opentelemetry-go-compile-instrumentation#1512 ·
维护者通常 3 天内回复
-
难度 1/5 1 小时以内 新手友好度 86/100
OpenPrinting/go-mfp#124 ·
维护者通常 1 天内回复