From 10bf6bd3583dc854c7a3188cf1c2449469d0bf56 Mon Sep 17 00:00:00 2001 From: Anshul Khandelwal Date: Wed, 17 Jan 2024 17:05:24 +0530 Subject: [PATCH 1/3] cancellation fix --- statement.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/statement.go b/statement.go index b0357275..74d565d3 100644 --- a/statement.go +++ b/statement.go @@ -203,13 +203,19 @@ func (s *stmt) execute(ctx context.Context, args []driver.NamedValue) (*C.duckdb } defer C.duckdb_destroy_pending(&pendingRes) - done := make(chan bool) + done := make(chan struct{}) defer close(done) + queryComplete := false go func() { select { case <-ctx.Done(): - // also need to interrupt to cancel the query + // sometimes this goroutine is not scheduled immediately and by that time if another query is scheduled on this connection + // this can cancel that query so need to handle cases when original query was complete. + if queryComplete { + return + } + // need to interrupt to cancel the query C.duckdb_interrupt(*s.c.con) return case <-done: @@ -218,16 +224,16 @@ func (s *stmt) execute(ctx context.Context, args []driver.NamedValue) (*C.duckdb }() var res C.duckdb_result - if state := C.duckdb_execute_pending(pendingRes, &res); state == C.DuckDBError { + state := C.duckdb_execute_pending(pendingRes, &res) + queryComplete = true + if state == C.DuckDBError { if ctx.Err() != nil { return nil, ctx.Err() } - dbErr := C.GoString(C.duckdb_result_error(&res)) C.duckdb_destroy_result(&res) return nil, errors.New(dbErr) } - return &res, nil } From 1cf684374fa61f23f7166f205ae863cabb5ccb9f Mon Sep 17 00:00:00 2001 From: Anshul Khandelwal Date: Wed, 17 Jan 2024 17:06:31 +0530 Subject: [PATCH 2/3] cancellation fix --- statement.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/statement.go b/statement.go index 74d565d3..4863e85e 100644 --- a/statement.go +++ b/statement.go @@ -230,10 +230,12 @@ func (s *stmt) execute(ctx context.Context, args []driver.NamedValue) (*C.duckdb if ctx.Err() != nil { return nil, ctx.Err() } + dbErr := C.GoString(C.duckdb_result_error(&res)) C.duckdb_destroy_result(&res) return nil, errors.New(dbErr) } + return &res, nil } From be560b9f05571b250fd311f04c6a119d7f49798b Mon Sep 17 00:00:00 2001 From: Anshul Khandelwal Date: Wed, 17 Jan 2024 17:07:00 +0530 Subject: [PATCH 3/3] cancellation fix --- statement.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/statement.go b/statement.go index 4863e85e..bc016e75 100644 --- a/statement.go +++ b/statement.go @@ -235,7 +235,7 @@ func (s *stmt) execute(ctx context.Context, args []driver.NamedValue) (*C.duckdb C.duckdb_destroy_result(&res) return nil, errors.New(dbErr) } - + return &res, nil }