Skip to content

Commit a0e6569

Browse files
committed
more tests, added doc comment
1 parent 436a09d commit a0e6569

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

conn_batch.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,11 @@ func (b *batch) closeQuery() error {
320320
return nil
321321
}
322322

323+
// Close will end the current INSERT without sending the currently buffered rows, and release the connection.
324+
// This may result in zero row inserts if no rows were appended.
325+
// If a batch was already sent this does nothing.
326+
// This should be called via defer after a batch is opened to prevent
327+
// batches from falling out of scope and timing out.
323328
func (b *batch) Close() error {
324329
if b.sent || b.released {
325330
return nil

tests/batch_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package tests
1919

2020
import (
2121
"testing"
22+
"time"
2223

2324
"github.com/ClickHouse/clickhouse-go/v2"
2425
"github.com/stretchr/testify/require"
@@ -51,3 +52,73 @@ func TestBatchContextCancellation(t *testing.T) {
5152
// assert if connection is properly released after context cancellation
5253
require.NoError(t, conn.Exec(context.Background(), "SELECT 1"))
5354
}
55+
56+
func TestBatchCloseConnectionReleased(t *testing.T) {
57+
te, err := GetTestEnvironment(testSet)
58+
require.NoError(t, err)
59+
opts := ClientOptionsFromEnv(te, clickhouse.Settings{}, false)
60+
opts.MaxOpenConns = 1
61+
conn, err := GetConnectionWithOptions(&opts)
62+
require.NoError(t, err)
63+
64+
b, err := conn.PrepareBatch(context.Background(), "INSERT INTO function null('x UInt64')")
65+
require.NoError(t, err)
66+
for i := 0; i < 100; i++ {
67+
require.NoError(t, b.Append(i))
68+
}
69+
70+
err = b.Close()
71+
require.NoError(t, err)
72+
73+
// assert if connection is properly released after close called
74+
require.NoError(t, conn.Exec(context.Background(), "SELECT 1"))
75+
}
76+
77+
func TestBatchSendConnectionReleased(t *testing.T) {
78+
te, err := GetTestEnvironment(testSet)
79+
require.NoError(t, err)
80+
opts := ClientOptionsFromEnv(te, clickhouse.Settings{}, false)
81+
opts.MaxOpenConns = 1
82+
conn, err := GetConnectionWithOptions(&opts)
83+
require.NoError(t, err)
84+
85+
b, err := conn.PrepareBatch(context.Background(), "INSERT INTO function null('x UInt64')")
86+
require.NoError(t, err)
87+
for i := 0; i < 100; i++ {
88+
require.NoError(t, b.Append(i))
89+
}
90+
91+
err = b.Send()
92+
require.NoError(t, err)
93+
94+
// Close should be deferred after the batch is opened
95+
// Validate that it can be called after Send
96+
err = b.Close()
97+
require.NoError(t, err)
98+
99+
// assert if connection is properly released after Send called
100+
require.NoError(t, conn.Exec(context.Background(), "SELECT 1"))
101+
}
102+
103+
// This test validates that connections are blocked if a batch is not properly
104+
// cleaned up. This isn't required behavior, but this test confirms it happens.
105+
func TestBatchCloseConnectionHold(t *testing.T) {
106+
te, err := GetTestEnvironment(testSet)
107+
require.NoError(t, err)
108+
opts := ClientOptionsFromEnv(te, clickhouse.Settings{}, false)
109+
opts.MaxOpenConns = 1
110+
opts.DialTimeout = 2 * time.Second // Lower timeout for faster acquire error
111+
conn, err := GetConnectionWithOptions(&opts)
112+
require.NoError(t, err)
113+
114+
b, err := conn.PrepareBatch(context.Background(), "INSERT INTO function null('x UInt64')")
115+
require.NoError(t, err)
116+
for i := 0; i < 100; i++ {
117+
require.NoError(t, b.Append(i))
118+
}
119+
120+
// batch.Close() should be called here
121+
122+
// assert if connection is blocked if close is not called.
123+
require.ErrorIs(t, conn.Exec(context.Background(), "SELECT 1"), clickhouse.ErrAcquireConnTimeout)
124+
}

0 commit comments

Comments
 (0)