diff --git a/runtime/drivers/clickhouse/context.go b/runtime/drivers/clickhouse/context.go index b50f72854d8..c3fa5d8678d 100644 --- a/runtime/drivers/clickhouse/context.go +++ b/runtime/drivers/clickhouse/context.go @@ -31,7 +31,12 @@ func connFromContext(ctx context.Context) *sqlx.Conn { // This is used to use certain session aware features like temporary tables. func (c *connection) sessionAwareContext(ctx context.Context) context.Context { if c.opts.Protocol == clickhouse.HTTP { - settings := maps.Clone(c.opts.Settings) + var settings map[string]any + if len(c.opts.Settings) == 0 { + settings = make(map[string]any) + } else { + settings = maps.Clone(c.opts.Settings) + } settings["session_id"] = uuid.New().String() return clickhouse.Context(ctx, clickhouse.WithSettings(settings)) } diff --git a/runtime/drivers/clickhouse/olap_test.go b/runtime/drivers/clickhouse/olap_test.go index 57bce3a204d..9a0fbf0cb8e 100644 --- a/runtime/drivers/clickhouse/olap_test.go +++ b/runtime/drivers/clickhouse/olap_test.go @@ -2,6 +2,7 @@ package clickhouse_test import ( "context" + "database/sql" "fmt" "testing" @@ -25,6 +26,7 @@ func TestClickhouseSingle(t *testing.T) { olap, ok := conn.AsOLAP("default") require.True(t, ok) + t.Run("WithConnection", func(t *testing.T) { testWithConnection(t, olap) }) t.Run("RenameView", func(t *testing.T) { testRenameView(t, olap) }) t.Run("RenameTable", func(t *testing.T) { testRenameTable(t, olap) }) t.Run("CreateTableAsSelect", func(t *testing.T) { testCreateTableAsSelect(t, olap) }) @@ -52,6 +54,7 @@ func TestClickhouseCluster(t *testing.T) { prepareClusterConn(t, olap, cluster) + t.Run("WithConnection", func(t *testing.T) { testWithConnection(t, olap) }) t.Run("RenameView", func(t *testing.T) { testRenameView(t, olap) }) t.Run("RenameTable", func(t *testing.T) { testRenameTable(t, olap) }) t.Run("CreateTableAsSelect", func(t *testing.T) { testCreateTableAsSelect(t, olap) }) @@ -62,6 +65,33 @@ func TestClickhouseCluster(t *testing.T) { t.Run("TestDictionary", func(t *testing.T) { testDictionary(t, olap) }) } +func testWithConnection(t *testing.T, olap drivers.OLAPStore) { + err := olap.WithConnection(context.Background(), 1, false, func(ctx, ensuredCtx context.Context, conn *sql.Conn) error { + err := olap.Exec(ctx, &drivers.Statement{ + Query: "CREATE table tbl engine=Memory AS SELECT 1 AS id, 'Earth' AS planet", + }) + require.NoError(t, err) + + res, err := olap.Execute(ctx, &drivers.Statement{ + Query: "SELECT id, planet FROM tbl", + }) + require.NoError(t, err) + var ( + id int + planet string + ) + for res.Next() { + err = res.Scan(&id, &planet) + require.NoError(t, err) + require.Equal(t, 1, id) + } + require.NoError(t, res.Err()) + require.NoError(t, res.Close()) + return nil + }) + require.NoError(t, err) +} + func testRenameView(t *testing.T, olap drivers.OLAPStore) { ctx := context.Background() opts := &drivers.CreateTableOptions{