Skip to content

Commit 28b2f5d

Browse files
authored
Fix serialization for slices of OrderedMap/IterableOrderedMap (#1365) (#1418)
1 parent a7f1fc4 commit 28b2f5d

File tree

2 files changed

+67
-11
lines changed

2 files changed

+67
-11
lines changed

lib/column/array.go

+6-11
Original file line numberDiff line numberDiff line change
@@ -192,22 +192,17 @@ func appendNullableRowPlain[T any](col *Array, arr []*T) error {
192192
func (col *Array) append(elem reflect.Value, level int) error {
193193
if level < col.depth {
194194
switch elem.Kind() {
195+
// allows to traverse pointers to slices and slices cast to `any`
196+
case reflect.Interface, reflect.Ptr:
197+
if !elem.IsNil() {
198+
return col.append(elem.Elem(), level)
199+
}
195200
// reflect.Value.Len() & reflect.Value.Index() is called in `append` method which is only valid for
196201
// Slice, Array and String that make sense here.
197202
case reflect.Slice, reflect.Array, reflect.String:
198203
col.appendOffset(level, uint64(elem.Len()))
199204
for i := 0; i < elem.Len(); i++ {
200-
el := elem.Index(i)
201-
202-
if el.Kind() == reflect.Interface && !el.IsNil() {
203-
el = el.Elem()
204-
}
205-
206-
if el.Kind() == reflect.Ptr && !el.IsNil() {
207-
el = el.Elem()
208-
}
209-
210-
if err := col.append(el, level+1); err != nil {
205+
if err := col.append(elem.Index(i), level+1); err != nil {
211206
return err
212207
}
213208
}

tests/issues/1365_test.go

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package issues
2+
3+
import (
4+
"context"
5+
"github.com/ClickHouse/clickhouse-go/v2/lib/column"
6+
"github.com/ClickHouse/clickhouse-go/v2/tests"
7+
"github.com/stretchr/testify/require"
8+
"testing"
9+
)
10+
11+
type T1365OrderedMap int
12+
13+
func (t *T1365OrderedMap) Put(k any, v any) {
14+
if k == "K" && v == "V" {
15+
*t = 0xDEDEDEAD
16+
}
17+
}
18+
func (t *T1365OrderedMap) Iterator() column.MapIterator { return t }
19+
func (t *T1365OrderedMap) Next() bool { *t++; return *t == 1 }
20+
func (t *T1365OrderedMap) Key() any { return "K" }
21+
func (t *T1365OrderedMap) Value() any { return "V" }
22+
23+
func TestIssue1365(t *testing.T) {
24+
ctx := context.Background()
25+
26+
conn, err := tests.GetConnection("issues", nil, nil, nil)
27+
require.NoError(t, err)
28+
defer conn.Close()
29+
30+
const ddl = `
31+
CREATE TABLE test_1365 (
32+
Col1 Array(Map(String,String))
33+
) Engine MergeTree() ORDER BY tuple()
34+
`
35+
err = conn.Exec(ctx, ddl)
36+
require.NoError(t, err)
37+
defer conn.Exec(ctx, "DROP TABLE test_1365")
38+
39+
batch, err := conn.PrepareBatch(ctx, "INSERT INTO test_1365")
40+
require.NoError(t, err)
41+
42+
var writeMaps []column.IterableOrderedMap
43+
writeMaps = append(writeMaps, new(T1365OrderedMap))
44+
writeMaps = append(writeMaps, new(T1365OrderedMap))
45+
46+
err = batch.Append(writeMaps)
47+
require.NoError(t, err)
48+
49+
err = batch.Send()
50+
require.NoError(t, err)
51+
52+
rows, err := conn.Query(ctx, "SELECT * FROM test_1365")
53+
require.NoError(t, err)
54+
55+
require.True(t, rows.Next())
56+
57+
//var readMaps []*T1365OrderedMap
58+
//
59+
//err = rows.Scan(&readMaps)
60+
//require.NoError(t, err)
61+
}

0 commit comments

Comments
 (0)