ColTuple issue when using proto.Named() helper
nikita-vanyasin opened this issue · 1 comments
Describe the bug
Steps to reproduce
(code taken from slightly adjusted tuple_test.go):
require.NoError(t, conn.Do(ctx, Query{
Body: "CREATE TABLE named_tuples (`1` Tuple(`s` String, `i` Int64, `m` Map(String, Float32))) ENGINE = Memory",
}))
// ...
var (
// ...
mapData = proto.Named[map[string]float32](
proto.NewMap[string, float32](new(proto.ColStr), new(proto.ColFloat32)),
"m",
)
)
results := proto.Results{
{Name: "1", Data: proto.ColTuple{strData, intData, mapData}},
}
require.NoError(t, conn.Do(ctx, Query{
Body: "SELECT * FROM named_tuples",
Result: results,
}))
Error log
Error: Received unexpected error:
decode block:
github.com/ClickHouse/ch-go.(*Client).Do.func5
/home/nikita/work/ch-go/query.go:729
- decode block:
github.com/ClickHouse/ch-go.(*Client).decodeBlock
/home/nikita/work/ch-go/query.go:245
- raw block:
github.com/ClickHouse/ch-go/proto.(*Block).DecodeBlock
/home/nikita/work/ch-go/proto/block.go:282
- target:
github.com/ClickHouse/ch-go/proto.(*Block).DecodeRawBlock
/home/nikita/work/ch-go/proto/block.go:269
- infer:
github.com/ClickHouse/ch-go/proto.Results.DecodeResult
/home/nikita/work/ch-go/proto/results.go:129
- infer:
github.com/ClickHouse/ch-go/proto.ColTuple.Infer
/home/nikita/work/ch-go/proto/col_tuple.go:121
- named:
github.com/ClickHouse/ch-go/proto.(*ColNamed[...]).Infer
/home/nikita/work/ch-go/proto/col_tuple.go:44
- invalid map type:
github.com/ClickHouse/ch-go/proto.(*ColMap[...]).Infer
/home/nikita/work/ch-go/proto/col_map.go:186
The issue happens only when using proto.Named
helper because it returns reference to new ColName obj instead of obj itself. This causes Infer
function does not work properly for this case:
it passes (Tuple(String, Int64, Map(String, Float32)))
into each of column.Infer call instead of parsing each column separately.
To fix the issue I had to replace
mapData = proto.ColNamed[map[string]float32]{
ColumnOf: proto.NewMap[string, float32](new(proto.ColStr), new(proto.ColFloat32)),
Name: "m",
}
with
mapData = proto.Named[map[string]float32](
proto.NewMap[string, float32](new(proto.ColStr), new(proto.ColFloat32)),
"m",
)
In general, this is just usability issue: I've spent a few hours trying to debug why my code don't work - only because I've used (seemingly harmless) helper function proto.Named
. I think interfaces should be adjusted to ensure the result of proto.Named()
can't be used as element of ColTuple
list. At least some clarification needed about what elements should be passed to ColTuple.