From c4f2973683ef7828858bce9df2bfe94258ece567 Mon Sep 17 00:00:00 2001 From: Anshul Khandelwal Date: Tue, 9 Jan 2024 11:08:05 +0530 Subject: [PATCH 1/3] interrupt query on ctx cancel/timeout --- statement.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/statement.go b/statement.go index ad777ec2..23e2dad4 100644 --- a/statement.go +++ b/statement.go @@ -207,6 +207,8 @@ func (s *stmt) execute(ctx context.Context, args []driver.NamedValue) (*C.duckdb select { // if context is cancelled or deadline exceeded, don't execute further case <-ctx.Done(): + // also need to interrupt to cancel the query + C.duckdb_interrupt(*s.c.con) return nil, ctx.Err() default: // continue From e3fc93e7267f8cf7de53a209d6650c6eb8bae227 Mon Sep 17 00:00:00 2001 From: Anshul Khandelwal Date: Tue, 9 Jan 2024 12:19:57 +0530 Subject: [PATCH 2/3] adding unit test --- duckdb_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/duckdb_test.go b/duckdb_test.go index bd278d16..fde020dc 100644 --- a/duckdb_test.go +++ b/duckdb_test.go @@ -1100,6 +1100,22 @@ func TestParquetExtension(t *testing.T) { require.NoError(t, err) } +func TestQueryTimeout(t *testing.T) { + db := openDB(t) + defer db.Close() + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + now := time.Now() + _, err := db.ExecContext(ctx, "CREATE TABLE test AS SELECT * FROM range(10000000) t1, range(1000000) t2;") + require.True(t, errors.Is(err, context.DeadlineExceeded)) + + // a very defensive time check, but should be good enough + // the query takes much longer than 10 seconds + require.Less(t, time.Since(now), 10*time.Second) +} + func openDB(t *testing.T) *sql.DB { db, err := sql.Open("duckdb", "") require.NoError(t, err) From 0c6d535ddc6a41eaf15845bfb7bf6eaa4f112b04 Mon Sep 17 00:00:00 2001 From: Anshul Khandelwal Date: Tue, 9 Jan 2024 12:25:12 +0530 Subject: [PATCH 3/3] adding unit test - reduce timeout --- duckdb_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/duckdb_test.go b/duckdb_test.go index fde020dc..d9303973 100644 --- a/duckdb_test.go +++ b/duckdb_test.go @@ -1104,12 +1104,12 @@ func TestQueryTimeout(t *testing.T) { db := openDB(t) defer db.Close() - ctx, cancel := context.WithTimeout(context.Background(), time.Second) + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*250) defer cancel() now := time.Now() _, err := db.ExecContext(ctx, "CREATE TABLE test AS SELECT * FROM range(10000000) t1, range(1000000) t2;") - require.True(t, errors.Is(err, context.DeadlineExceeded)) + require.ErrorIs(t, err, context.DeadlineExceeded) // a very defensive time check, but should be good enough // the query takes much longer than 10 seconds