Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ All notable changes to PL/Ruby are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and the project aims to follow [Semantic Versioning](https://semver.org/).

## [Unreleased]
## [2.5.0] - 2026-07-06

PL/Python parity: per-function `$_SD` storage, a raw-binary `bytea` mapping, SPI
result column metadata, and an `ltree` transform. With these, PL/Ruby is at or
ahead of PL/Python across the board. The core changes are in the shared library;
`ALTER EXTENSION plruby UPDATE` completes the upgrade after installing the new
binary. The `ltree` transform ships as the separate `ltree_plruby` extension.

### Added

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ MODULE_big = plruby
OBJS = plruby.o plruby_io.o plruby_spi.o

EXTENSION = plruby
DATA = plruby--2.0.sql plruby--2.1.sql plruby--2.2.sql plruby--2.3.sql plruby--2.4.sql plruby--2.0--2.1.sql plruby--2.1--2.2.sql plruby--2.2--2.3.sql plruby--2.3--2.4.sql
DATA = plruby--2.0.sql plruby--2.1.sql plruby--2.2.sql plruby--2.3.sql plruby--2.4.sql plruby--2.5.sql plruby--2.0--2.1.sql plruby--2.1--2.2.sql plruby--2.2--2.3.sql plruby--2.3--2.4.sql plruby--2.4--2.5.sql

# Ruby compile/link flags, discovered via RbConfig.
RUBY ?= ruby
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[![CI](https://github.com/commandprompt/plruby/actions/workflows/ci.yml/badge.svg)](https://github.com/commandprompt/plruby/actions/workflows/ci.yml)
[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-11_to_18-336791?logo=postgresql&logoColor=white)](https://www.postgresql.org/)
[![Ruby](https://img.shields.io/badge/Ruby-3.x-CC342D?logo=ruby&logoColor=white)](https://www.ruby-lang.org/)
[![Tests](https://img.shields.io/badge/tests-42_passing-brightgreen)](sql/)
[![Tests](https://img.shields.io/badge/tests-44_passing-brightgreen)](sql/)
[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)

</div>
Expand Down Expand Up @@ -45,11 +45,11 @@ SELECT hello('world'); -- Hello, world!
| 🔁 **Set-returning functions** | `RETURNS SETOF` / `RETURNS TABLE` with `return_next`. |
| ⚡ **Triggers** | Row & statement triggers via `$_TD` (with `'SKIP'` / `'MODIFY'`). |
| 📣 **Event triggers** | Back `CREATE EVENT TRIGGER` with `RETURNS event_trigger`. |
| 🗄️ **Database access (SPI)** | `spi_exec`, `spi_fetch_row`, `spi_processed`, `spi_status`, `spi_rewind`. |
| 🗄️ **Database access (SPI)** | `spi_exec`, `spi_fetch_row`, `spi_processed`, `spi_status`, `spi_rewind`, and result column metadata (`spi_colnames` / `spi_coltypes` / `spi_coltypmods`). |
| 🌊 **Cursor streaming** | `spi_query` (block or handle), `spi_fetchrow`, `spi_cursor_close`, `Cursor#each`. Consume large results without materializing them. |
| 📝 **Prepared statements** | `spi_prepare` / `spi_exec_prepared` / `spi_query_prepared` / `spi_freeplan`. |
| 🔐 **Transaction control** | `spi_commit` / `spi_rollback` in procedures, plus `subtransaction` blocks. |
| 🧰 **Utilities** | `quote_literal` / `quote_nullable` / `quote_ident`, `elog`, `$_SHARED`. |
| 🧰 **Utilities** | `quote_literal` / `quote_nullable` / `quote_ident`, `elog`, session-shared `$_SHARED`, and per-function `$_SD`. |
| 📦 **Session setup** | Anonymous `DO` blocks, `plruby_modules` autoloading, and a `plruby.start_proc` hook. |
| 🔄 **Transforms** | `jsonb_plruby`, `hstore_plruby`, and `ltree_plruby`: functions declared `TRANSFORM FOR TYPE` exchange native Ruby Hashes/Arrays with `jsonb`, `hstore`, and `ltree`. |

Expand Down
11 changes: 11 additions & 0 deletions plruby--2.4--2.5.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* Upgrade PL/Ruby from 2.4 to 2.5.
*
* Every 2.5 change lives in the shared library ($_SD per-function storage, the
* bytea<->binary String mapping, and the spi_colnames/spi_coltypes/
* spi_coltypmods result accessors); the ltree transform is a separate
* extension (ltree_plruby). The core extension's SQL-level objects are
* unchanged, so this script has nothing to do beyond moving the version.
*/

-- complain if script is sourced in psql, rather than via ALTER EXTENSION
\echo Use "ALTER EXTENSION plruby UPDATE TO '2.5'" to load this file. \quit
32 changes: 32 additions & 0 deletions plruby--2.5.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* PL/Ruby language, packaged as an extension.
*
* The language is UNTRUSTED (created without the TRUSTED attribute): on modern
* Ruby there is no sandbox ($SAFE was removed in Ruby 3.0), so PL/Ruby
* functions can do anything the server's OS user can. Creating them is
* therefore restricted to superusers.
*/

-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION plruby" to load this file. \quit

CREATE FUNCTION plruby_call_handler()
RETURNS language_handler
AS 'MODULE_PATHNAME'
LANGUAGE C;

CREATE FUNCTION plruby_inline_handler(internal)
RETURNS void
AS 'MODULE_PATHNAME'
LANGUAGE C;

CREATE FUNCTION plruby_validator(oid)
RETURNS void
AS 'MODULE_PATHNAME'
LANGUAGE C;

CREATE LANGUAGE plruby
HANDLER plruby_call_handler
INLINE plruby_inline_handler
VALIDATOR plruby_validator;

COMMENT ON LANGUAGE plruby IS 'PL/Ruby procedural language (untrusted)';
2 changes: 1 addition & 1 deletion plruby.control
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
# superuser-only to install and the language is created without the TRUSTED
# attribute.
comment = 'PL/Ruby procedural language (untrusted)'
default_version = '2.4'
default_version = '2.5'
module_pathname = '$libdir/plruby'
relocatable = false
Loading