

Writing UDFs in Golang
source link: https://www.splitgraph.com/blog/seafowl-udf-golang
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Writing UDFs in Golang
We return to the wide world of WASM. In our previous round we implemented a UDF using Rust; today we're porting it to Golang.
Seafowl has supported UDFs for some time now, and they continue to offer an exciting way for Seafowl users to significantly extend functionality in a fully sandboxed environment. Recently, in response to user request, we added a Golang example.
To learn more about compiling Golang to WASM, read on.
Handling UDF requirements
There are certain requirements incumbent on the UDF implementer when it comes to running UDFs in Seafowl, and Golang is included. Today we cover a partial list:
- reading data in from the host through linear raw memory
- returning the computed result as a msgpack-encoded buffer
- working around Golang default syntax (e.g. TitleCase function exports)
- compiling Golang into WASM
Reading data in
As discussed previously, when you register a Seafowl UDF it's required to specify certain parameters including e.g. wasm_export
(e.g. addi64), return_type
(e.g. BIGINT), input_types
(e.g. BIGINT).
This is important because raw memory is the medium for passing data between Seafowl and the UDF. By specifying the parameter types upfront at UDF registration time, both Seafowl host and UDF know how to properly encode/decode the data they share with each other. That's why the function addi64
, expects a pointer to a buffer vs conventional Go function params.
Writing data out
Conversely, when we return the result to Seafowl, we need to return a buffer that includes the length of the result first, with the actual msgpack-encoded result appended afterwards.
This allows Seafowl's query engine to return the result of the UDF in the typical way.
TitleCase function export workaround
Golang conventionally uses TitleCase to indicate when a function should be exported from its module scope. Some may find it cute and this convention is presumably fine in traditional Golang, but in certain contexts like UDFs, we are required to provide alloc
/dealloc
functions in lower case - which poses a fun hurdle.
Fortunately, while researching how tinygo
works, I learned it supports annotating functions regardless of casing via
//export $functionName
For example:
//export alloc
func alloc(size uintptr) unsafe.Pointer {
...
}
And Seafowl will be able to call this function in the required way.
Compiling Golang into WASM
In August 2023 the Golang team shipped WASI/WASM support, so the following approach we used may no longer be strictly necessary these days.
When we tackled this project, Golang did not yet support WASM natively so looking elsewhere, we found Tinygo.
It turns out we can generate a WASM module ready for import into Seafowl via:
tinygo build -o seafowl-udf-go.wasm -target=wasi
NOTE: it's necessary to include -target=wasi
.
Recap
In this post we reviewed some of the steps taken to port the Rust-based UDF into Golang. This was my first Golang project and I appreciated the opportunity to work at the lower level, learn about byteslice manipulation, msgpack serialization, WASI and more.
If you build a cool UDF, please consider letting us know!
Image credits
[liantomtit](https://unsplash.com/@liantomtit), [evanescentlight](https://unsplash.com/@evanescentlight)Recommend
-
109
Writing an Interactive Message Bot for Slack in GolangHey everyone, @deeeet here, from the Site Reliability Engineering (SRE) team.At...
-
130
Writing a JIT compiler in GolangTL;DR A simple JIT compiler in golang. Scroll down to bottom for working code.A JIT compiler (
-
56
-
33
At PASS Summit a few weeks ago, Microsoft released CTP2.1 of SQL Server 2019, and one of the big feature enhancements that is included in the CTP is
-
31
Introduction I’ve been programming with Go for almost 5 years now, and it’s been almost as long since I first created a Lambda function. This article will cover what I’ve learnt over the past few years, writing serverle...
-
14
How do Mesh VPNs work? Writing my own VPN tool in Golang to find out 07 Jul 2021 tldr: I created a mesh VPN networking tool named
-
14
Excelize Introduction Excelize is a library written in pure Go providing a set of functions that allow you to write to and read from XLSX / XLSM / XLTM / XLTX files. Supports reading and writing spreadsheet documents generat...
-
2
UDFs as Query Builders in FaunaDB’s FQL For a recent project, my team created an event-based app that would be used for just a few weeks. We wanted to be able to answer questions such as, “How many new accounts were a...
-
11
Kotlin API for Apache Spark v1.2: UDTs, UDFs, RDDs, Compatibility, and More!
-
3
Microsoft Visual FoxPro DBF for Go Golang package for reading and writing FoxPro dBase table and memo files. Features There are several similar packages but they are not suited for our use case, this packa...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK