# PL/pgSQL Executor Implementation in malisper/pgrust: Understanding REAL-OR-LOUD

> Explore the PL/pgSQL executor implementation in malisper/pgrust. Discover how REAL-OR-LOUD separates control-flow logic from value-substrate seams using a Rust port.

- Repository: [Michael Malis/pgrust](https://github.com/malisper/pgrust)
- Tags: internals
- Published: 2026-07-13

---

**The PL/pgSQL executor implementation in malisper/pgrust is a line-by-line Rust port of PostgreSQL's [`pl_exec.c`](https://github.com/malisper/pgrust/blob/main/pl_exec.c) that uses a REAL-OR-LOUD discipline to separate fully ported control-flow logic from intentionally panicking value-substrate seams.**

The `malisper/pgrust` project reimplements PostgreSQL's procedural language infrastructure in Rust, located in the `crates/pl/plpgsql/src/exec` directory. This article examines how the **PL/pgSQL executor implementation** recreates the original C execution skeleton while tracking porting progress through a strict binary classification system.

## What Is the PL/pgSQL Executor Implementation?

The executor serves as the runtime engine for compiled PL/pgSQL functions. It traverses the `PLpgSQL_function` abstract syntax tree and dispatches to handlers for every statement type—including **IF**, **CASE**, **LOOP**, **WHILE**, **FOR**, **FOREACH**, **EXIT**, and **RETURN** nodes.

As implemented in `malisper/pgrust`, the executor mirrors the exact arm order, SQLSTATE messages, and return-code propagation (`LOOP_RC_PROCESSING`) from the original PostgreSQL C file [`pl_exec.c`](https://github.com/malisper/pgrust/blob/main/pl_exec.c). The implementation preserves the original control-flow skeleton while replacing C-specific mechanisms like `longjmp`/`PG_TRY` with Rust-native error channels.

## The REAL-OR-LOUD Porting Philosophy

The **REAL-OR-LOUD** discipline governs every boundary between the ported Rust code and the underlying PostgreSQL value system. Each seam must be classified as either fully functional (REAL) or deliberately unimplemented (LOUD).

### REAL Components (Control-Flow Logic)

**REAL** designates code that is fully ported 1:1 from C. This includes the statement-dispatch functions (`exec_stmt_*`), loop handling mechanics, block exception sub-transactions, and the error-propagation channel that replaces C's exception handling. When execution flows through REAL code, it behaves identically to the original PostgreSQL implementation, processing control structures without calling into unported value-level operations.

### LOUD Seams (Value Substrate)

**LOUD** marks the "value substrate"—every operation that evaluates an expression, executes a query via SPI, reads or writes a **Datum**, iterates arrays, or deconstructs composite types. These operations route through *seams* that invoke `panic!` (i.e., fail loudly) and embed the original C callee name and subsystem (such as executor `ExprState`, plan-based SPI surfaces, or array and fmgr substrates). In a production C build, these paths would trigger `ereport` or `elog`; in pgrust they crash immediately to surface missing ports during testing.

### The Binary Classification Rule

According to [`src/exec/src/seam.rs`](https://github.com/malisper/pgrust/blob/main/src/exec/src/seam.rs) and [`src/handler/src/seam.rs`](https://github.com/malisper/pgrust/blob/main/src/handler/src/seam.rs), each seam must follow the **REAL-OR-LOUD** rule: the functionality is either complete (REAL) or it panics (LOUD). This binary classification eliminates ambiguous partial implementations and forces any missing behavior to be explicit and observable during test execution.

## Executor Architecture and Key Functions

The executor operates through three distinct layers that bridge the REAL control flow with LOUD value operations.

### Inward Seams and Callback Registration

The inward seam layer installs compile-time callbacks such as `plpgsql_exec_get_datum_type_info` via `init_seams`. These hooks allow the executor to query type information without directly accessing unported catalog functions, maintaining the boundary between REAL logic and LOUD substrate.

### Core Execution Functions

The execution core implements the statement dispatcher and block handler:

- **`exec_toplevel_block`** – Entry point for executing a compiled PL/pgSQL function, initializing the `PLpgSQL_execstate` context
- **`exec_stmt_block`** – Processes block-level statements, handling variable scoping and exception trapping
- **`loop_rc_processing`** – Manages the `LOOP_RC_PROCESSING` return-code table that tracks exit conditions for loop control structures

These functions reside in [`crates/pl/plpgsql/src/exec/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/pl/plpgsql/src/exec/lib.rs) and constitute the REAL skeleton that orchestrates statement execution.

### Outward Seams and Panic Behavior

Value-level operations flow through outward seams defined in [`crates/pl/plpgsql/src/exec/seam.rs`](https://github.com/malisper/pgrust/blob/main/crates/pl/plpgsql/src/exec/seam.rs). Any call that touches the SQL executor, SPI, or datum handling routes through these seams. For example, calling `seam::exec_eval_expr(expr, estate)` evaluates an expression through the SPI bridge, but will panic if the underlying C implementation is not yet provided.

## Error Handling Without longjmp

The Rust executor replaces PostgreSQL's `longjmp`/`PG_TRY` exception mechanism with structured error propagation. Instead of unwinding the C stack via longjmp, the executor uses Rust's `Result` types and error channels to propagate `PgError` values upward through `exec_toplevel_block` and related functions. This preserves the original error semantics while using memory-safe Rust patterns.

## Key Source Files in the Implementation

The executor spans several crates that separate concerns between control flow, seam definitions, and trigger handling:

- **[`crates/pl/plpgsql/src/exec/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/pl/plpgsql/src/exec/lib.rs)** – Core executor implementation containing the control-flow skeleton, loop handling, and error propagation logic
- **[`crates/pl/plpgsql/src/exec/seam.rs`](https://github.com/malisper/pgrust/blob/main/crates/pl/plpgsql/src/exec/seam.rs)** – Definition of outward seams that expose the LOUD value substrate
- **[`crates/pl/plpgsql/src/handler/src/seam.rs`](https://github.com/malisper/pgrust/blob/main/crates/pl/plpgsql/src/handler/src/seam.rs)** – Mirrors executor seams for the PL/pgSQL handler ([`pl_handler.c`](https://github.com/malisper/pgrust/blob/main/pl_handler.c))
- **[`crates/pl/plpgsql/src/plpgsql_exec_seams/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/pl/plpgsql/src/plpgsql_exec_seams/src/lib.rs)** – Registers and manages both REAL and LOUD seams, providing the callback infrastructure
- **[`crates/pl/plpgsql/src/exec/src/trigger.rs`](https://github.com/malisper/pgrust/blob/main/crates/pl/plpgsql/src/exec/src/trigger.rs)** – DML trigger entry point implementing `plpgsql_exec_trigger`
- **[`crates/pl/plpgsql/src/exec/src/mem.rs`](https://github.com/malisper/pgrust/blob/main/crates/pl/plpgsql/src/exec/src/mem.rs)** – Memory management helpers used during statement execution

## Code Examples

### Executing a Top-Level Block

To execute a compiled PL/pgSQL function, initialize the execution state and invoke the top-level block handler:

```rust
let mut estate = PLpgSQL_execstate::new(...);
let block = compiled_function.stmts[0].as_block(); // PLpgSQL_stmt_block
let result = plpgsql_exec::exec_toplevel_block(&mut estate, block)?;
// `result` is PLpgSQL_rc_result – either OK or an Err(PgError)

```

### Installing a REAL Seam

Compile-time callbacks can be installed to provide REAL implementations for specific operations:

```rust
plpgsql_exec_seams::install_get_datum_type_info(|param| {
    // REAL implementation of make_datum_param
});

```

### Encountering a LOUD Seam

When execution hits unported value logic, the seam panics with diagnostic information:

```rust
let datum = seam::exec_eval_expr(expr, estate)?;   // panics if the SPI bridge is not ported

```

## Summary

- The **PL/pgSQL executor implementation** in `malisper/pgrust` is a faithful Rust recreation of PostgreSQL's [`pl_exec.c`](https://github.com/malisper/pgrust/blob/main/pl_exec.c), located in `crates/pl/plpgsql/src/exec`
- **REAL** code handles control flow (loops, conditionals, blocks) and is fully ported from C
- **LOUD** seams handle value operations (SPI, Datums, expressions) and deliberately panic to expose unimplemented functionality
- The **REAL-OR-LOUD** binary classification eliminates ambiguity and forces explicit porting status
- Core functions like `exec_toplevel_block`, `exec_stmt_block`, and `loop_rc_processing` form the REAL execution skeleton
- Error propagation replaces C's `longjmp` with Rust `Result` types and error channels

## Frequently Asked Questions

### What is the REAL-OR-LOUD pattern in pgrust?

**REAL-OR-LOUD** is a binary classification system where every seam in the PL/pgSQL executor must be either **REAL** (fully ported from C and functional) or **LOUD** (intentionally panicking to mark unimplemented value-level operations). This pattern appears in [`src/exec/src/seam.rs`](https://github.com/malisper/pgrust/blob/main/src/exec/src/seam.rs) and ensures that missing functionality crashes loudly during testing rather than failing silently or behaving unexpectedly.

### How does the Rust executor handle errors without C's longjmp?

The executor replaces PostgreSQL's `longjmp`/`PG_TRY` mechanism with Rust-native error propagation using `Result` types and error channels. According to the source in [`crates/pl/plpgsql/src/exec/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/pl/plpgsql/src/exec/lib.rs), the error-propagation channel carries `PgError` values upward through the call stack, allowing `exec_toplevel_block` to return execution status without invoking C-style stack unwinding.

### Which PL/pgSQL features are currently REAL versus LOUD?

**REAL** features include the statement dispatcher (`exec_stmt_*` functions), all loop constructs (handling via `loop_rc_processing`), block-level exception management, and control-flow logic. **LOUD** features cover the value substrate: expression evaluation through `seam::exec_eval_expr`, SPI query execution, Datum read/write operations, array iteration, and composite type deconstruction. Any operation touching these value layers routes through seams that panic if the underlying C bridge is absent.

### Where is the PL/pgSQL executor code located in the repository?

The executor implementation resides in the `crates/pl/plpgsql/src/exec/` directory. The main control flow lives in [`lib.rs`](https://github.com/malisper/pgrust/blob/main/lib.rs), seam definitions are in [`seam.rs`](https://github.com/malisper/pgrust/blob/main/seam.rs), and supporting modules include [`trigger.rs`](https://github.com/malisper/pgrust/blob/main/trigger.rs) for DML triggers and [`mem.rs`](https://github.com/malisper/pgrust/blob/main/mem.rs) for memory management. Seam registration and management occur in [`crates/pl/plpgsql/src/plpgsql_exec_seams/src/lib.rs`](https://github.com/malisper/pgrust/blob/main/crates/pl/plpgsql/src/plpgsql_exec_seams/src/lib.rs).