diff --git a/lib/column/array.go b/lib/column/array.go index 8f0ca08e02..2a0c17d40d 100644 --- a/lib/column/array.go +++ b/lib/column/array.go @@ -192,22 +192,17 @@ func appendNullableRowPlain[T any](col *Array, arr []*T) error { func (col *Array) append(elem reflect.Value, level int) error { if level < col.depth { switch elem.Kind() { + // allows to traverse pointers to slices and slices cast to `any` + case reflect.Interface, reflect.Ptr: + if !elem.IsNil() { + return col.append(elem.Elem(), level) + } // reflect.Value.Len() & reflect.Value.Index() is called in `append` method which is only valid for // Slice, Array and String that make sense here. case reflect.Slice, reflect.Array, reflect.String: col.appendOffset(level, uint64(elem.Len())) for i := 0; i < elem.Len(); i++ { - el := elem.Index(i) - - if el.Kind() == reflect.Interface && !el.IsNil() { - el = el.Elem() - } - - if el.Kind() == reflect.Ptr && !el.IsNil() { - el = el.Elem() - } - - if err := col.append(el, level+1); err != nil { + if err := col.append(elem.Index(i), level+1); err != nil { return err } } diff --git a/tests/issues/1365_test.go b/tests/issues/1365_test.go new file mode 100644 index 0000000000..46561e1e08 --- /dev/null +++ b/tests/issues/1365_test.go @@ -0,0 +1,61 @@ +package issues + +import ( + "context" + "github.com/ClickHouse/clickhouse-go/v2/lib/column" + "github.com/ClickHouse/clickhouse-go/v2/tests" + "github.com/stretchr/testify/require" + "testing" +) + +type T1365OrderedMap int + +func (t *T1365OrderedMap) Put(k any, v any) { + if k == "K" && v == "V" { + *t = 0xDEDEDEAD + } +} +func (t *T1365OrderedMap) Iterator() column.MapIterator { return t } +func (t *T1365OrderedMap) Next() bool { *t++; return *t == 1 } +func (t *T1365OrderedMap) Key() any { return "K" } +func (t *T1365OrderedMap) Value() any { return "V" } + +func TestIssue1365(t *testing.T) { + ctx := context.Background() + + conn, err := tests.GetConnection("issues", nil, nil, nil) + require.NoError(t, err) + defer conn.Close() + + const ddl = ` + CREATE TABLE test_1365 ( + Col1 Array(Map(String,String)) + ) Engine MergeTree() ORDER BY tuple() + ` + err = conn.Exec(ctx, ddl) + require.NoError(t, err) + defer conn.Exec(ctx, "DROP TABLE test_1365") + + batch, err := conn.PrepareBatch(ctx, "INSERT INTO test_1365") + require.NoError(t, err) + + var writeMaps []column.IterableOrderedMap + writeMaps = append(writeMaps, new(T1365OrderedMap)) + writeMaps = append(writeMaps, new(T1365OrderedMap)) + + err = batch.Append(writeMaps) + require.NoError(t, err) + + err = batch.Send() + require.NoError(t, err) + + rows, err := conn.Query(ctx, "SELECT * FROM test_1365") + require.NoError(t, err) + + require.True(t, rows.Next()) + + //var readMaps []*T1365OrderedMap + // + //err = rows.Scan(&readMaps) + //require.NoError(t, err) +}