ClickHouse/ch-go

bug: UNEXPECTED_PACKET_FROM_CLIENT after context cancellation

Closed this issue · 0 comments

Connection gets unusable (always returns an error) after context cancellation.

Reproducible example:

package main

import (
	"context"
	"fmt"
	"github.com/ClickHouse/ch-go"
	"github.com/ClickHouse/ch-go/proto"
	"github.com/stretchr/testify/require"
	"testing"
)

const tableName = "ch_go_test"

func Test1(t *testing.T) {
	c, err := ch.Dial(context.Background(), ch.Options{})
	require.NoError(t, err)
	err = c.Do(context.Background(), ch.Query{
		Body: fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (v Int32) ENGINE = GenerateRandom(0, 0, 0)", tableName),
	})
	require.NoError(t, err)
	for i := 1; ; i++ {
		var (
			rows int
			data proto.ColInt32
		)
		ctx, cancel := context.WithCancel(context.Background())
		err = c.Do(ctx, ch.Query{
			Body:   fmt.Sprintf("SELECT * FROM %s LIMIT %d", tableName, 1_000_000),
			Result: proto.Results{{Name: "v", Data: &data}},
			OnResult: func(_ context.Context, block proto.Block) error {
				rows += block.Rows
				if 500_000 < rows {
					cancel()
				}
				return nil
			},
		})
		cancel()
		if err != nil {
			require.ErrorIs(t, err, context.Canceled, "rows #%d, iteration #%d", rows, i)
		}
	}
}

In my case code above 100% ends up with:

=== RUN   Test1
    main_test.go:40: 
        	Error Trace:	/home/u/GolandProjects/ch-go-test/main_test.go:40
        	Error:      	Target error should be in err chain:
        	            	expected: "context canceled"
        	            	in chain: "handle packet: UNEXPECTED_PACKET_FROM_CLIENT (101): DB::NetException: Unexpected packet Hello received from client"
        	            		"UNEXPECTED_PACKET_FROM_CLIENT (101): DB::NetException: Unexpected packet Hello received from client"
        	Test:       	Test1
        	Messages:   	rows #0, iteration #3
--- FAIL: Test1 (0.01s)