Skip to content

Commit

Permalink
tidy tests, add pinner, other nits
Browse files Browse the repository at this point in the history
  • Loading branch information
taniabogatsch committed Sep 19, 2024
1 parent 7fd79ca commit 493f151
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 209 deletions.
10 changes: 4 additions & 6 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,10 @@ var (
errInvalidDecimalWidth = fmt.Errorf("the DECIMAL with must be between 1 and %d", MAX_DECIMAL_WIDTH)
errInvalidDecimalScale = errors.New("the DECIMAL scale must be less than or equal to the width")

errScalarUDFCreate = errors.New("could not create scalar UDF")
errScalarUDFNoName = fmt.Errorf("%w: missing name", errScalarUDFCreate)
errScalarUDFIsNil = fmt.Errorf("%w: function is nil", errScalarUDFCreate)
errScalarUDFNoExecutor = fmt.Errorf("%w: executor is nil", errScalarUDFCreate)
//errScalarUDFNilInputTypes = fmt.Errorf("%w: input types are nil", errScalarUDFCreate)
//errScalarUDFEmptyInputTypes = fmt.Errorf("%w: empty input types", errScalarUDFCreate)
errScalarUDFCreate = errors.New("could not create scalar UDF")
errScalarUDFNoName = fmt.Errorf("%w: missing name", errScalarUDFCreate)
errScalarUDFIsNil = fmt.Errorf("%w: function is nil", errScalarUDFCreate)
errScalarUDFNoExecutor = fmt.Errorf("%w: executor is nil", errScalarUDFCreate)
errScalarUDFInputTypeIsNil = fmt.Errorf("%w: input type is nil", errScalarUDFCreate)
errScalarUDFResultTypeIsNil = fmt.Errorf("%w: result type is nil", errScalarUDFCreate)
errScalarUDFResultTypeIsANY = fmt.Errorf("%w: result type is ANY, which is not supported", errScalarUDFCreate)
Expand Down
16 changes: 16 additions & 0 deletions pinner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package duckdb

import "runtime"

type pinnedValue[T any] struct {
pinner *runtime.Pinner
value T
}

type unpinner interface {
unpin()
}

func (v pinnedValue[T]) unpin() {
v.pinner.Unpin()
}
15 changes: 12 additions & 3 deletions scalar_udf.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import "C"
import (
"database/sql"
"database/sql/driver"
"runtime"
"runtime/cgo"
"unsafe"
)
Expand Down Expand Up @@ -134,9 +135,9 @@ func setFuncError(function_info C.duckdb_function_info, msg string) {
func scalar_udf_callback(function_info C.duckdb_function_info, input C.duckdb_data_chunk, output C.duckdb_vector) {
extraInfo := C.duckdb_scalar_function_get_extra_info(function_info)

// extraInfo is a void* pointer to our ScalarFunc.
// extraInfo is a void* pointer to our pinned ScalarFunc f.
h := *(*cgo.Handle)(unsafe.Pointer(extraInfo))
function := h.Value().(ScalarFunc)
function := h.Value().(pinnedValue[ScalarFunc]).value

// Initialize the input chunk.
var inputChunk DataChunk
Expand Down Expand Up @@ -203,6 +204,7 @@ func scalar_udf_callback(function_info C.duckdb_function_info, input C.duckdb_da
//export scalar_udf_delete_callback
func scalar_udf_delete_callback(extraInfo unsafe.Pointer) {
h := (*cgo.Handle)(extraInfo)
h.Value().(unpinner).unpin()
h.Delete()
}

Expand Down Expand Up @@ -282,8 +284,15 @@ func createScalarFunc(name string, f ScalarFunc) (C.duckdb_scalar_function, erro
// Set the function callback.
C.duckdb_scalar_function_set_function(function, C.scalar_udf_callback_t(C.scalar_udf_callback))

// Pin the ScalarFunc f.
value := pinnedValue[ScalarFunc]{
pinner: &runtime.Pinner{},
value: f,
}
h := cgo.NewHandle(value)
value.pinner.Pin(&h)

// Set data available during execution.
h := cgo.NewHandle(f)
C.duckdb_scalar_function_set_extra_info(
function,
unsafe.Pointer(&h),
Expand Down
Loading

0 comments on commit 493f151

Please sign in to comment.