ByteBulletin

[tooling] · · 2 min read

uplpgsql Brings JIT-Compiled PL/pgSQL to PostgreSQL — Control Flow, Now Native

A new open-source extension compiles PostgreSQL's PL/pgSQL functions to native code via LLVM, promising order-of-magnitude speedups for procedural logic.

By ByteBulletin Editors · Editorial Team


A new open-source project from the NEXTGRES team offers a dramatic departure from PostgreSQL's venerable PL/pgSQL interpreter. uplpgsql is a JIT-compiling procedural language handler that compiles PL/pgSQL functions to native machine code on first execution, bypassing the traditional tree-walking interpreter entirely.

The key insight: PostgreSQL's own JIT support compiles SQL expressions and tuple deforming, but leaves procedural control flow (IF statements, loops, assignments) as interpreted switch-dispatch overhead. uplpgsql compiles the control flow itself, turning statements into LLVM basic blocks and branches, loops into real machine loops, and variable accesses into direct struct-offset loads. The result is that anything that spends significant time in PL/pgSQL logic — not just SQL queries — could see major performance gains.

Using it is as simple as installing the extension and changing LANGUAGE plpgsql to LANGUAGE uplpgsql. All GUCs are mirrored under the uplpgsql. prefix, and function recompilation happens automatically on CREATE OR REPLACE.

How It Works

Under the hood, uplpgsql is built on the Universal Procedural Language (UPL) compiler and runtime. Control flow, arithmetic, and datum access are emitted as native IR instructions. Operations that inherently require PostgreSQL's C infrastructure — SPI calls, expression evaluation, tuplestores, subtransactions — delegate to runtime helpers.

A three-tier expression system handles operators:

  • Integer and float arithmetic compiles to LLVM overflow intrinsics with zero call overhead.
  • Most other operators resolve their C function pointer at compile time, bypassing the function manager (fmgr).
  • The remainder falls back to a runtime helper as an escape hatch.

Crucially, uplpgsql links its own LLVM and owns its LLJIT instance. PostgreSQL does not need to be built --with-llvm; a stock server runs JIT-compiled PL/pgSQL just fine.

Status and Caveats

uplpgsql is pre-alpha and explicitly not production-ready. The README warns of crashes, correctness issues, and data loss. It requires PostgreSQL 20devel and LLVM 15+ (tested against LLVM 22). The build is C-only and uses the LLVM C API.

The project's ambition extends beyond PL/pgSQL: the underlying UPL compiler is language-agnostic, and the architecture is designed to support other procedural dialects by swapping the parser front-end while reusing the same compilation primitives.

For developers willing to experiment on non-critical systems, uplpgsql offers a glimpse of a future where PostgreSQL procedural languages run at native speed — and the only cost is changing one word in your function definitions.

SHARE

← All stories