Skip to content

Commit

Permalink
Fix insertion of empty map into JSON column by using _dummy subcolumn (
Browse files Browse the repository at this point in the history
…#1116)

* test: issue 1113 (insertion of empty map in JSON column)

Signed-off-by: Leonardo Di Donato <[email protected]>

* fix(lib/column): correctly handle empty maps in JSON columns

Signed-off-by: Leonardo Di Donato <[email protected]>

---------

Signed-off-by: Leonardo Di Donato <[email protected]>
  • Loading branch information
leodido authored Oct 11, 2023
1 parent 4f115fc commit 478c1cd
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lib/column/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,13 @@ func appendStructOrMap(jCol *JSONObject, data any) error {
Err: fmt.Errorf("map keys must be string for column %s", jCol.Name()),
}
}
if jCol.columns == nil && vData.Len() == 0 {
// if map is empty, we need to create an empty Tuple to make sure subcolumns protocol is happy
// _dummy is a ClickHouse internal name for empty Tuple subcolumn
// it has the same effect as `INSERT INTO single_json_type_table VALUES ('{}');`
jCol.upsertValue("_dummy", "Int8")
return jCol.insertEmptyColumn("_dummy")
}
return iterateMap(vData, jCol, 0)
}
return &UnsupportedColumnTypeError{
Expand Down
39 changes: 39 additions & 0 deletions tests/issues/1113_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package issues

import (
"context"
"testing"

"github.com/ClickHouse/clickhouse-go/v2"
clickhouse_tests "github.com/ClickHouse/clickhouse-go/v2/tests"
"github.com/stretchr/testify/require"
)

func Test1113(t *testing.T) {
var (
conn, err = clickhouse_tests.GetConnection("issues", clickhouse.Settings{
"max_execution_time": 60,
"allow_experimental_object_type": true,
}, nil, &clickhouse.Compression{
Method: clickhouse.CompressionLZ4,
})
)
ctx := context.Background()
require.NoError(t, err)
const ddl = "CREATE TABLE test_1113 (col_1 JSON, col_2 JSON) Engine MergeTree() ORDER BY tuple()"
require.NoError(t, conn.Exec(ctx, ddl))
defer func() {
conn.Exec(ctx, "DROP TABLE IF EXISTS test_1113")
}()

batch, err := conn.PrepareBatch(context.Background(), "INSERT INTO test_1113")
require.NoError(t, err)

v1 := map[string]struct {
Str string
}{"a": {Str: "value"}}
v2 := map[string]any{}

require.NoError(t, batch.Append(v1, v2))
require.NoError(t, batch.Send())
}

0 comments on commit 478c1cd

Please sign in to comment.