-- -- Additional scalar types with no dedicated Ruby representation: uuid, inet, -- enums, and domains. All travel as strings; constraints and input -- validation stay on the PostgreSQL side. -- -- uuid round-trips as its canonical lower-case text form. CREATE FUNCTION u_echo(uuid) RETURNS uuid LANGUAGE plruby AS $$ args[0] $$; SELECT u_echo('A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11'); u_echo -------------------------------------- a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 (1 row) CREATE FUNCTION u_class(uuid) RETURNS text LANGUAGE plruby AS $$ args[0].class.name $$; SELECT u_class('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'); u_class --------- String (1 row) -- inet/cidr as strings; the network math stays in SQL. CREATE FUNCTION net_echo(inet) RETURNS inet LANGUAGE plruby AS $$ args[0] $$; SELECT net_echo('192.168.100.128/25'); net_echo -------------------- 192.168.100.128/25 (1 row) SELECT net_echo('::1'); net_echo ---------- ::1 (1 row) -- An enum arrives as its label and may be returned as one. CREATE TYPE mt_mood AS ENUM ('sad', 'ok', 'happy'); CREATE FUNCTION mood_up(mt_mood) RETURNS mt_mood LANGUAGE plruby AS $$ order_ = ['sad', 'ok', 'happy'] order_[[order_.index(args[0]) + 1, order_.length - 1].min] $$; SELECT mood_up('sad'), mood_up('ok'), mood_up('happy'); mood_up | mood_up | mood_up ---------+---------+--------- ok | happy | happy (1 row) -- Returning a label that is not part of the enum is rejected. CREATE FUNCTION mood_bad() RETURNS mt_mood LANGUAGE plruby AS $$ 'ecstatic' $$; SELECT mood_bad(); ERROR: invalid input value for enum mt_mood: "ecstatic" CONTEXT: PL/Ruby function "mood_bad" -- Domains: values returned into a domain are checked by its constraint. CREATE DOMAIN mt_posint AS int CHECK (VALUE > 0); CREATE FUNCTION pos_ok(int) RETURNS mt_posint LANGUAGE plruby AS $$ args[0] $$; SELECT pos_ok(5); pos_ok -------- 5 (1 row) SELECT pos_ok(-5); ERROR: value for domain mt_posint violates check constraint "mt_posint_check" CONTEXT: PL/Ruby function "pos_ok" -- A domain-typed argument arrives as its base type's Ruby value (the -- domain's constraints were already enforced when the value was created). CREATE FUNCTION pos_class(mt_posint) RETURNS text LANGUAGE plruby AS $$ "#{args[0].class.name}=#{args[0]}" $$; SELECT pos_class(41); pos_class ------------ Integer=41 (1 row) -- ... including a domain over an array type. CREATE DOMAIN mt_intlist AS int[] CHECK (array_length(VALUE, 1) <= 3); CREATE FUNCTION list_class(mt_intlist) RETURNS text LANGUAGE plruby AS $$ "#{args[0].class.name}=#{args[0].inspect}" $$; SELECT list_class(ARRAY[1, 2]); list_class -------------- Array=[1, 2] (1 row) DROP FUNCTION list_class(mt_intlist); DROP DOMAIN mt_intlist; DROP FUNCTION pos_class(mt_posint); DROP FUNCTION pos_ok(int); DROP DOMAIN mt_posint; DROP FUNCTION mood_up(mt_mood); DROP FUNCTION mood_bad(); DROP TYPE mt_mood;