Releases: commandprompt/plx
Release list
plx 1.3.1
Code-only patch release (no catalog changes) carrying the memory-safety and robustness fixes from the full-repo transpiler audit (#1). Upgrade with ALTER EXTENSION plx UPDATE TO '1.3.1' after installing the new module.
Fixed
- Missing capacity guard on the trailing
T_EOFtoken write inlex()(heap overflow / SIGSEGV when a source lexed to exactlycap-1tokens). plx_strbuildsb_ensure()int32doubling could wrap negative near ~1GB and spin while passing a bogus size torepalloc; growth is now 64-bit and clamped toMaxAllocSize.- The recursion-guarded transpiler entries now call
check_stack_depth(), so deeply nested input raises a clean error (honoringmax_stack_depth) instead of crashing the backend. - The Python lexer raises a clean "indentation nested too deeply" error at the indent-stack limit instead of emitting an unbalanced
T_INDENT. - Raw single-quoted strings in Ruby and PHP keep backslashes literal (only
\\and\'are special). - PHP
${name}curly interpolation in double-quoted strings is now recognized. - Non-decimal integer literals (
0x/0o/0b, with_separators) are lexed as one token and rewritten to decimal (portable to PG13-15); a >64-bit literal raises a clean "integer literal out of range" error.
Other
- Declare the built-in dialect descriptors in
plx.h, clearing-Wmissing-variable-declarations.
Verified against PostgreSQL 18.4: clean build, all 13 installcheck tests pass, and the 1.3.0 → 1.3.1 upgrade applies cleanly.
plx 1.3.0
plx 1.3.0 makes trigger row mutation available across the dialects and ships a verified cookbook for every dialect.
Added
- plxtsql trigger row mutation. A Transact-SQL trigger can now assign to
NEWfields withSET NEW.col = e, which lowers toNEW.col := e, so a trigger can rewrite the row and not only validate it. ASETwith a qualified target and a top-level=is an assignment;SET NOCOUNT ONand other session options are still ignored. With the plxphp arrow assignment added in 1.2.2, assigning to a trigger'sNEWfields is now supported across the dialects, each in its own idiom. - Cookbooks and limitations docs. A verified, runnable cookbook for each of the nine dialects (scalar functions, loops, string building, query loops, set-returning functions, error handling, triggers, dynamic SQL, and dialect idioms), and a consolidated gaps-and-limitations page. Both are on the documentation site.
No catalog changes. All 13 regression suites pass on PostgreSQL 13 through 18, plus 19beta and 20devel built from source.
Upgrade
Install the new module (make && make install), then:
ALTER EXTENSION plx UPDATE TO '1.3.0';A fresh CREATE EXTENSION plx lands on 1.3.0 directly. The PGXN distribution zip (plx-1.3.0.zip) is attached.
- Documentation: https://commandprompt.github.io/plx/
- Full changelog: https://github.com/commandprompt/plx/blob/v1.3.0/CHANGELOG.md
plx 1.2.2
A code-only patch release.
Fixed
- plxphp: assigning to a record field with the arrow form (
$NEW->col = e), the idiomatic PHP spelling, previously raised "unsupported operator in statement". It now lowers toNEW.col := e, so a trigger function can stampNEWfields with$NEW->col = e. The array-element form ($NEW['col'] = e) continues to work.
No catalog changes. The full 13-suite regression passes on PostgreSQL 13 through 18, plus 19beta2 and 20devel built from source.
Upgrade
Install the new module (make && make install), then:
ALTER EXTENSION plx UPDATE TO '1.2.2';A fresh CREATE EXTENSION plx lands on 1.2.2 directly. The PGXN distribution zip (plx-1.2.2.zip) is attached.
See CHANGELOG.md.
plx 1.2.1
A code-only patch release: plx now builds on PostgreSQL 19 and 20.
Fixed
- Build on PostgreSQL 19 and 20 with a C23 toolchain (for example gcc 15). There, PostgreSQL defines
pg_noreturnas the standard[[noreturn]]attribute, whose placement is strict. plx wrote it after the storage class (static pg_noreturn void ...), which C23 rejects, so plx did not compile on 19/20. It is now the first token of each declaration (pg_noreturn static void ...), matching PostgreSQL's own convention, and still compiles on 13 through 18.
The full 13-suite regression passes on PostgreSQL 13 through 18, plus 19beta2 and 20devel built from source. No catalog changes: the only change is in the loadable module.
Upgrade
Install the new module (make && make install), then:
ALTER EXTENSION plx UPDATE TO '1.2.1';A fresh CREATE EXTENSION plx lands on 1.2.1 directly. The PGXN distribution zip (plx-1.2.1.zip) is attached.
See CHANGELOG.md.
plx 1.2
plx 1.2 makes it nine dialects. Write a PostgreSQL function body in the language you already know; plx transpiles it to plpgsql at CREATE FUNCTION time and the standard plpgsql interpreter runs it. No language runtime is loaded into the backend, and the generated plpgsql is visible in the catalog.
Dialects (9)
plxruby · plxphp · plxjs · plxts (TypeScript) · plxpython3 · plxgo (Go) · plxcobol · plxplsql (Oracle PL/SQL) · plxtsql (Transact-SQL / SQL Server)
New since 1.1
- Four new dialects: Oracle PL/SQL, Transact-SQL (SQL Server), Go, and TypeScript. The SQL-family and Go dialects are restructuring front ends (own tokenizers/parsers); PL/SQL and TypeScript build on the near-plpgsql and JavaScript paths. See each chapter under
doc/. - COBOL tables:
OCCURS nmaps aWORKING-STORAGEitem to a PostgreSQL array, withWS-ARR(i)subscripts andPERFORM v OVER ARRAYiteration. - plpgsql completeness audit across dialects (OUT/INOUT/RETURNS TABLE/STRICT), a worked
examples/directory, anddoc/DEBUGGING.md+ aplx_source()helper. - Whole-project hardening: a fresh-eyes review of every front end plus mutation fuzzing of all nine dialects fixed real backend crashes, hangs, and wrong/invalid-output cases. The fuzzer (
test/fuzz.py) and corpus now cover all nine dialects and are crash- and hang-clean.
Compatibility
All 13 regression suites pass on PostgreSQL 13 through 18 (CI + local matrix). plx_strbuild's in-place fast path (amortized-O(1) string append) is accelerated on PostgreSQL 18; correct but unaccelerated on 13–17.
Install
Build from source (make && make install), then CREATE EXTENSION plx;. Upgrade from an earlier install with ALTER EXTENSION plx UPDATE TO '1.2';. A PGXN distribution zip (plx-1.2.0.zip) is attached.
See CHANGELOG.md for the full list.
plx 1.1.1
plx 1.1.1 is a code-only patch release (no catalog changes). It restores
compilation on PostgreSQL 13-15 and fixes several plxcobol bugs found in review.
Upgrade an existing install with:
ALTER EXTENSION plx UPDATE TO '1.1.1';Fixed
- Compilation on PostgreSQL 13, 14, and 15.
plx_strbuild.cincluded
varatt.hunconditionally, but that header was only split out ofpostgres.h
in PostgreSQL 16, so 1.1 did not build on 13-15. The full 9-suite regression
now passes on PostgreSQL 13 through 18 (verified in CI). - plxcobol crash (out-of-bounds read) on a body truncated at
PERFORM VARYING ... UNTIL; it now errors cleanly. - plxcobol
ADD a b GIVING cand other multi-addendADD/SUBTRACTforms
were rejected; they are parsed as operand lists now. - plxcobol multi-argument function calls (
mod(a, b)) were broken because
the tokenizer stripped commas everywhere; commas inside parentheses are kept. - plxcobol
GREATER/LESS ... OR EQUALat the end of a condition, aPICTURE
repeat-count overflow, and unterminated string handling.
Added
- Continuous integration (GitHub Actions) running the full suite on PostgreSQL
13 through 18 (green). - plxcobol coverage in the fuzzer and corpus runner.
- A PGXN
META.json, and theplx-1.1.1.zipdistribution attached to this
release.
Compatibility
Builds and passes the full regression suite on PostgreSQL 13, 14, 15, 16, 17,
and 18.
plx 1.1
plx 1.1 adds plxcobol, a COBOL dialect (ISO/IEC 1989:2023, COBOL 2023, free
format), at full plpgsql construct parity. As with the other dialects, a COBOL
function body is transpiled to plpgsql at CREATE FUNCTION time and runs on the
standard plpgsql interpreter, with no separate language runtime in the backend.
plxcobol
COBOL is verb-driven and free-format, so it has its own front end (tokenizer and
recursive-descent parser). Data names map to plpgsql identifiers (lower-cased,
hyphens to underscores). Coverage:
WORKING-STORAGEdeclarations, withPICTUREmapped to SQL types, plusTYPE
(for%ROWTYPE,RECORD,refcursor) andCONSTANT AS.MOVE/COMPUTEand theADD/SUBTRACT/MULTIPLY/DIVIDEverbs;
**is exponent and%is modulo.IF/ELSE/END-IF;EVALUATE(simple and searchedEVALUATE TRUE).PERFORMin theUNTIL,VARYING,TIMES, inline, query (OVER "sql") and
array (OVER ARRAY) forms;EXIT PERFORM [CYCLE].GOBACK RETURNING,RETURN-NEXT,RETURN-QUERY;EXECUTEwithUSING/INTO;
cursors (OPEN-CURSOR/FETCH-CURSOR/MOVE-CURSOR/CLOSE-CURSOR).- Exception handling (
BEGIN-TRY/WHEN/END-TRY) with stacked diagnostics via
GET;GET ROW-COUNT;FOUND. STRING-APPEND <expr> TO <var>, which lowers to theplx_strbuildstring
builder (amortized-O(1) in-loop string building).RAISE,DISPLAY,ASSERT,CALL,COMMIT/ROLLBACK.
See doc/plxcobol.md
and the parity matrix in
doc/PARITY.md.
Performance
plxcobol transpiles to plpgsql like the other dialects, so it matches plpgsql on
the arithmetic, iteration, string-building, and call workloads; see
bench/BENCHMARKS.md.
Upgrading
Existing 1.0 installations upgrade in place:
ALTER EXTENSION plx UPDATE TO '1.1';A fresh CREATE EXTENSION plx installs 1.1 directly.
Compatibility
Tested against PostgreSQL 13 through 18; the full regression suite (nine suites,
including plxcobol) passes on each.
plx 1.0
plx lets you write PostgreSQL stored functions and triggers in a Ruby, PHP,
JavaScript, or Python dialect. At CREATE FUNCTION time the body is transpiled
to plpgsql and stored in pg_proc.prosrc; at run time it executes on the
standard plpgsql interpreter, with no separate language runtime in the backend.
Highlights
- Dialect-pluggable front end (growing set):
plxruby,plxphp,plxjs,
plxpython3, each at full plpgsql construct parity. Language names carry a
plxprefix, so the extension coexists with native PL/Ruby and PL/PHP. - The generated plpgsql is visible in
pg_proc.prosrcand re-transpile is
idempotent (a sentinel comment records the version and embeds the original
source). plx_strbuild, an expanded-object string builder with amortized-O(1) append,
addressing plpgsql's O(n^2) in-loop string concatenation. The dialect append
operators (s << x,$s .= x,s += xon a string) lower onto it. On
PostgreSQL 18 this is about 170x faster thans := s || 'x'and faster than
the native PLs' own append; on PostgreSQL 13 to 17 it is correct but not
accelerated (the in-place path needs a PostgreSQL 18 planner feature).- Benchmarks against plpgsql, the plx dialects, PL/Perl, PL/Python3, and native
PL/Ruby and PL/PHP. Regression suite, corpus runner, and fuzzer. - Full documentation: per-dialect chapters, a plpgsql parity matrix, a user
guide, an architecture document, and a transpiler specification.
Compatibility
Tested against PostgreSQL 13, 14, 15, 16, 17, and 18. The full regression suite
passes on each.
Install
make PG_CONFIG=/path/to/pg_config
make install PG_CONFIG=/path/to/pg_config
CREATE EXTENSION plx;See the CHANGELOG
for the full list.