ducktinycc

DuckDB-C-Erweiterung für im Prozess JIT-kompilierte C-UDFs über TinyCC — eigenständig, keine externe Laufzeitumgebung erforderlich

Maintainer: sounkou-bioinfo

Installation und Laden

INSTALL ducktinycc FROM community;
LOAD ducktinycc;

Beispiel

-- 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 := 'varchar',
arg_types := []
);
-- Call the registered C UDF
SELECT hello_from_c() AS msg;

Über ducktinycc

DuckTinyCC kompiliert und registriert C-Skalar-UDFs aus SQL mit TinyCC (libtcc), im Prozess.

Wichtige SQL-Einstiegspunkte:

Function Purpose
tcc_module(…) Sitzungskonfiguration, Build-Staging, Codegenerierung, Kompilierung, Registrierung
tcc_system_paths(…) Effektive TinyCC-Include-/Bibliothekssuchpfade anzeigen
tcc_library_probe(…) Kandidatenbibliotheksdateien und normalisierte Linknamen prüfen

Compile-/Codegen- und C-Typ-Hilfsmodi (über tcc_module):

Mode Purpose
quick_compile Einmalig Quelle + Codegenerierung + Kompilierung + Registrierung
compile Kompilieren/Registrieren aus vorgestagten Sitzungsquellen/-bindungen
codegen_preview Generierten Wrapper-C-Quelltext ohne Kompilierung/Laden ausgeben
c_struct Struct-Hilfs-UDFs aus Feldspezifikationen erzeugen und registrieren
c_union Union-Hilfs-UDFs aus Feldspezifikationen erzeugen und registrieren
c_bitfield Bitfield-Struct-Hilfs-UDFs erzeugen und registrieren
c_enum Enum-Konstanten-Hilfs-UDFs erzeugen und registrieren

Namensschema der generierten Hilfsfunktionen:

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

Unterstützung für Typsignaturen (return_type / arg_types):

Token family Examples
Scalars void (nur Rückgabe), bool, i8/u8/i16/u16/i32/u32/i64/u64, f32/f64, ptr, varchar, blob, uuid, date, time, timestamp, interval, decimal
Composites (recursive) list, type[], type[N], structname:type;..., map<key_type;value_type>, unionname:type;...

Entsprechungen der SQL-↔-C-Brücke:

SQL token family C bridge type
varchar const char *
blob 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 ducktinycc_decimal_t (DuckDB DECIMAL(18,3) bei der Registrierung)

Ergebnisschemas der Funktionen:

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-/Laufzeitmodell:

  • Wrapper werden aus return_type/arg_types erzeugt und über ducktinycc_register_signature(…) registriert
  • wrapper_mode unterstützt zeilen- und batchweise Ausführungspfade
  • Code wird im Speicher kompiliert + relokiert (kein separates Shared-Library-Artefakt)
  • Die zweimalige Registrierung desselben sql_name in einer Sitzung liefert false/E_INIT_FAILED (plattformübergreifend konsistent); vor erneuter Registrierung mit tcc_new_state zurücksetzen

Stabilität von Skalar-UDFs:

  • compile, quick_compile und codegen_preview akzeptieren stability := ‘consistent’ | ‘volatile’
  • tinycc_bind kann die Stabilität für eine spätere Kompilierung vorbereiten; ein expliziter stability-Wert bei compile/quick_compile/codegen_preview überschreibt den vorgestagten Wert
  • Verwenden Sie volatile für RNGs, Zähler, Uhren, Allokation, I/O, Callbacks oder Lesezugriffe auf veränderlichen externen Speicher, damit DuckDB die Funktion erneut ausführt und Seiteneffekte nicht constant-foldet
  • Generierte Hilfsmodi setzen intern eine explizite Hilfsstabilität: reine Metadaten-/Enum-Helfer sind consistent, während Allokations-/Free-/Setter-/Getter-Helfer für veränderlichen Speicher volatile sind

Eingebettete Laufzeitumgebung (eigenständig):

  • libtcc1.a und alle TinyCC-Include-Header (stdarg.h, stddef.h, tccdefs.h usw.) werden zur Build-Zeit in die Erweiterungsbinary eingebettet
  • Beim ersten compile- oder quick_compile-Aufruf extrahiert tcc_ensure_embedded_runtime() sie in ein inhaltshash-adressiertes temporäres Verzeichnis (z. B. /tmp/ducktinycc_/)
  • Folgeaufrufe im selben Prozess nutzen dieses Verzeichnis erneut, ohne erneut zu extrahieren
  • Nach der Bereitstellung ist keine separate TinyCC-Installation oder Laufzeitpfadkonfiguration nötig
  • tcc_system_paths() zeigt den aktiven Laufzeitpfad und, ob er aus der eingebetteten Extraktion aufgelöst wurde

Projektdetails und Beispiele: https://github.com/sounkou-bioinfo/DuckTinyCC

Community package excludes WASM targets.

Additional Notes: Generated and helper functions are SQL scalar UDFs; only tcc_module(…), tcc_system_paths(…), and tcc_library_probe(…) are table functions. For library linking, we can pass short names (m, z, c), explicit filenames (libfoo.so, foo.dll, .a, .lib), or path-like values. Because DuckTinyCC uses -nostdlib by default, use library := ‘c’ when generated code needs libc symbols that are not otherwise injected. Pointer helpers are low-level interop tools; for most workflows, handle-based access is safer than raw tcc_dataptr

Hinzugefügte Funktionen

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

Überladene Funktionen

Diese Erweiterung fügt keine Funktionsüberladungen hinzu.

Hinzugefügte Typen

Diese Erweiterung fügt keine Typen hinzu.

Hinzugefügte Einstellungen

Diese Erweiterung fügt keine Einstellungen hinzu.