Search Shortcut cmd + k | ctrl + k
ducktinycc

DuckDB C extension for in-process JIT compiled C UDFs via TinyCC

Maintainer(s): Sounkou Mahamane Toure

Installing and Loading

INSTALL ducktinycc FROM community;
LOAD ducktinycc;

Example

-- Load the extension
LOAD ducktinycc;

-- Compile and register a simple C function as a SQL UDF
SELECT ok, mode, code
FROM tcc_module(
  mode := 'quick_compile',
  source := 'const char *hello_from_c(void){ return "hello from C"; }',
  symbol := 'hello_from_c',
  sql_name := 'hello_from_c',
  return_type := 'cstring',
  arg_types := []
);

-- Call the registered C UDF 
SELECT hello_from_c() AS msg;

About ducktinycc

DuckTinyCC compiles and registers C scalar UDFs from SQL using TinyCC (libtcc), in-process.

Main SQL entrypoints:

Function Purpose
tcc_module(…) Session config, build staging, codegen, compile, registration
tcc_system_paths(…) Show effective TinyCC include/library search paths
tcc_library_probe(…) Probe candidate library files and normalized link names

Compile/codegen and C-type helper modes (via tcc_module):

Mode Purpose
quick_compile One-shot source + codegen + compile + register
compile Compile/register from staged session sources/bindings
codegen_preview Emit generated wrapper C source without compile/load
c_struct Generate + register struct helper UDFs from field specs
c_union Generate + register union helper UDFs from field specs
c_bitfield Generate + register bitfield struct helper UDFs
c_enum Generate + register enum constant helper UDFs

Generated helper naming:

Helper mode Generated SQL function pattern
c_struct struct__new/free/get_*/set_*/off_*/addr/sizeof/alignof
c_union union__new/free/get_*/set_*/off_*/addr/sizeof/alignof
c_bitfield struct__get_*/set_*/sizeof/alignof
c_enum enum__, enum__sizeof

Type signature support (return_type / arg_types):

Token family Examples
Scalars void (return only), bool/boolean, i8/u8/i16/u16/i32/u32/i64/u64, f32/f64, ptr/pointer/c_ptr, varchar/text/string/cstring, blob/bytea/binary/varbinary/buffer/bytes, uuid, date, time, timestamp/datetime, interval, decimal/numeric
Composites (recursive) list, type[], type[N], struct<name:type;...>, map<key_type;value_type>, union<name:type;...>
Legacy compatibility list_i64 style list tokens are still accepted

SQL <-> C bridge correspondences:

SQL token family C bridge type
varchar/text/string/cstring const char *
blob/bytea/binary/varbinary/buffer/bytes ducktinycc_blob_t
list<…>, type[] ducktinycc_list_t
type[N] ducktinycc_array_t
struct<…> ducktinycc_struct_t
map<…> ducktinycc_map_t
union<…> ducktinycc_union_t
decimal/numeric ducktinycc_decimal_t (DuckDB DECIMAL(18,3) at registration)

Function result schemas:

Function Result columns
tcc_module(…) ok BOOLEAN, mode VARCHAR, phase VARCHAR, code VARCHAR, message VARCHAR, detail VARCHAR, sql_name VARCHAR, symbol VARCHAR, artifact_id VARCHAR, connection_scope VARCHAR
tcc_system_paths(…) kind VARCHAR, key VARCHAR, value VARCHAR, exists BOOLEAN, detail VARCHAR
tcc_library_probe(…) kind VARCHAR, key VARCHAR, value VARCHAR, exists BOOLEAN, detail VARCHAR

Codegen/runtime model:

  • wrappers are generated from return_type/arg_types and registered through ducktinycc_register_signature(…)
  • wrapper_mode supports row and batch execution paths
  • code is compiled + relocated in-memory (no separate shared-library artifact)

Compile/runtime assets:

  • compile/quick_compile use a TinyCC runtime path (headers + libraries)
  • libtcc1.a is not strictly required for every compiled function; it is needed when generated code references TinyCC runtime helper symbols
  • extern/system-library bindings can work without libtcc1.a when those helper symbols are not required and libraries are resolvable

Project details and examples: https://github.com/sounkou-bioinfo/DuckTinyCC

Community package excludes WASM and Windows targets.

Added Functions

function_name function_type description comment examples
tcc_alloc scalar NULL NULL  
tcc_dataptr scalar NULL NULL  
tcc_free_ptr scalar NULL NULL  
tcc_library_probe table NULL NULL  
tcc_module table NULL NULL  
tcc_ptr_add scalar NULL NULL  
tcc_ptr_size scalar NULL NULL  
tcc_read_bytes scalar NULL NULL  
tcc_read_f32 scalar NULL NULL  
tcc_read_f64 scalar NULL NULL  
tcc_read_i16 scalar NULL NULL  
tcc_read_i32 scalar NULL NULL  
tcc_read_i64 scalar NULL NULL  
tcc_read_i8 scalar NULL NULL  
tcc_read_u16 scalar NULL NULL  
tcc_read_u32 scalar NULL NULL  
tcc_read_u64 scalar NULL NULL  
tcc_read_u8 scalar NULL NULL  
tcc_system_paths table NULL NULL  
tcc_write_bytes scalar NULL NULL  
tcc_write_f32 scalar NULL NULL  
tcc_write_f64 scalar NULL NULL  
tcc_write_i16 scalar NULL NULL  
tcc_write_i32 scalar NULL NULL  
tcc_write_i64 scalar NULL NULL  
tcc_write_i8 scalar NULL NULL  
tcc_write_u16 scalar NULL NULL  
tcc_write_u32 scalar NULL NULL  
tcc_write_u64 scalar NULL NULL  
tcc_write_u8 scalar NULL NULL