Skip to content

Add ltree_plruby: TRANSFORM FOR TYPE ltree#4

Merged
jdatcmd merged 1 commit into
masterfrom
feature/ltree-transform
Jul 7, 2026
Merged

Add ltree_plruby: TRANSFORM FOR TYPE ltree#4
jdatcmd merged 1 commit into
masterfrom
feature/ltree-transform

Conversation

@jdatcmd

@jdatcmd jdatcmd commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

New companion extension ltree_plruby providing TRANSFORM FOR TYPE ltree, closing the last identified PL/Python parity gap (mirrors the in-core ltree_plpython transform, ltree ↔ list).

An opted-in function receives an ltree argument as a Ruby Array of its label Strings'Top.Science.Astronomy'['Top', 'Science', 'Astronomy'] — and may return an Array of labels into an ltree result (elements stringified and joined with ., so an invalid label is rejected by ltree's own parser). The empty ltree maps to the empty Array; a NULL ltree is nil.

CREATE EXTENSION ltree_plruby CASCADE;

CREATE FUNCTION ancestors(path ltree) RETURNS SETOF ltree
TRANSFORM FOR TYPE ltree
LANGUAGE plruby AS $$
    (1..path.length).each { |n| return_next(path[0...n]) }
    nil
$$;

Design

Follows the hstore_plruby pattern exactly: it never touches ltree's internal representation. It converts through ltree's public ltree2text(ltree) / text2ltree(text) functions, resolved at run time via the pg_transform row that points at the transform function (schema/search_path independent) and cached in fn_extra. So it needs no ltree headers and works with the packaged ltree on PG 11–18.

Testing

New ltree_plruby regression suite: argument → Array, path operations (length/parent/reverse), build & round-trip, empty and NULL, non-Array rejection (clean error), SETOF/composite rows via return_next, trigger $_TD Array + 'MODIFY', and untransformed passthrough (still a String). Green on PG 12 and PG 18; wired into CI beside the jsonb/hstore transforms. INSTALL, README, and the language reference updated. Additive; no compatibility impact.

🤖 Generated with Claude Code

A new companion extension (ltree_plruby/) providing TRANSFORM FOR TYPE
ltree, mirroring the in-core ltree_plpython transform (ltree <-> list).

An opted-in function receives an ltree argument as a Ruby Array of its
label Strings ('Top.Science' -> ['Top','Science']) and may return an
Array of labels into an ltree result (elements stringified and joined
with '.', so an invalid label is rejected by ltree's own parser). The
empty ltree maps to the empty Array; a NULL ltree is nil.

Like hstore_plruby, it never touches ltree's internal representation:
it converts through ltree's public ltree2text(ltree)/text2ltree(text)
functions, resolved at run time via the pg_transform row that points at
the transform function (schema/search_path independent) and cached in
fn_extra. So it needs no ltree headers and works with the packaged ltree
on PG 11-18.

New ltree_plruby regression suite (arg->Array, path ops, build/round-trip,
empty and NULL, non-Array rejection, SETOF/composite via return_next,
trigger $_TD + MODIFY, untransformed passthrough). Wired into CI beside
the jsonb/hstore transforms; INSTALL/README/docs updated. Green on PG 12
and 18.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jdatcmd jdatcmd force-pushed the feature/ltree-transform branch from eed2cd0 to 36929d0 Compare July 7, 2026 03:17
@jdatcmd jdatcmd merged commit 0bcd4f1 into master Jul 7, 2026
9 checks passed
@jdatcmd jdatcmd deleted the feature/ltree-transform branch July 7, 2026 03:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant