Skip to content

ColTuple issue when using proto.Named() helper #393

Open
@nikita-vanyasin

Description

@nikita-vanyasin

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions