ClickHouse / clickhouse-go

Golang driver for ClickHouse
Apache License 2.0
2.87k stars 549 forks source link

QueryContext does not return query error #1268

Closed night1008 closed 5 months ago

night1008 commented 5 months ago

Expected behaviour

code: 160, message: The maximum sleep time is 3000000 microseconds. Requested: 300: while executing 'FUNCTION sleep(300 :: 0) -> sleep(300) UInt8 : 1'
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/ClickHouse/clickhouse-go/v2"
)

func main() {
    db := clickhouse.OpenDB(&clickhouse.Options{
        Addr: []string{"127.0.0.1:9000"},
        Auth: clickhouse.Auth{
            Database: "default",
            Username: "default",
            Password: "",
        },
        Settings: clickhouse.Settings{
            "join_use_nulls": 1,
        },
    })

    ctx := context.Background()
    conn, err := db.Conn(ctx)
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    sql := "select sleep(300)"
    rows, err := conn.QueryContext(ctx, sql)
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    fmt.Println(rows.Columns())
}
[sleep(300)] <nil>

Environment

jkaflik commented 5 months ago

Hi @night1008

Since the error is not thrown in ClickHouse at the time of query retrieval but later with the data packet, the client has to process data received from the server explicitly using rows.Next().

See code snippet:

package issues

import (
    "context"
    "testing"

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

func Test1268(t *testing.T) {
    conn, err := clickhouse_tests.GetDatabaseSQLConnection("issues", nil, nil, nil)
    require.NoError(t, err)

    rows, err := conn.QueryContext(context.Background(), "select sleep(300)")
    require.NoError(t, err)
    defer rows.Close()

    for rows.Next() {
        if rows.Err() != nil {
            break
        }
    }

    assert.ErrorContains(t, rows.Err(), "code: 160, message: The maximum sleep time is 3000000 microseconds.")
}

Perhaps you have any reason to not call rows.Next()?

night1008 commented 5 months ago

I see. Thanks!