-- -- Features ported from PL/Perl: DO blocks, prepared plans, quoting, elog. -- -- Anonymous code block (DO) DO $$ pg_raise('notice', 'hello from a DO block'); $$ LANGUAGE plphp; -- DO block that uses SPI DO $$ $r = spi_exec('select 42 as n'); $row = spi_fetch_row($r); pg_raise('notice', 'DO via SPI: ' . $row['n']); $$ LANGUAGE plphp; -- A syntactically invalid DO block is rejected DO $$ this is not php $$ LANGUAGE plphp; -- Prepared statements: prepare / exec_prepared / freeplan CREATE FUNCTION prep_test(int) RETURNS int LANGUAGE plphp AS $$ $plan = spi_prepare('select $1 * 10 as v', 'int4'); $r = spi_exec_prepared($plan, $args[0]); $row = spi_fetch_row($r); spi_freeplan($plan); return $row['v']; $$; SELECT prep_test(5); -- Prepared plan iterated over multiple rows CREATE FUNCTION prep_sum(int) RETURNS int LANGUAGE plphp AS $$ $plan = spi_prepare('select g from generate_series(1, $1) g', 'int4'); $r = spi_exec_prepared($plan, $args[0]); $total = 0; while ($row = spi_fetch_row($r)) $total += $row['g']; spi_freeplan($plan); return intval($total); $$; SELECT prep_sum(5); -- Prepared plan with two text arguments, and spi_processed CREATE FUNCTION prep_concat(text, text) RETURNS text LANGUAGE plphp AS $$ $plan = spi_prepare('select $1 || $2 as s', 'text', 'text'); $r = spi_exec_prepared($plan, $args[0], $args[1]); pg_raise('notice', 'rows: ' . spi_processed($r)); $row = spi_fetch_row($r); spi_freeplan($plan); return $row['s']; $$; SELECT prep_concat('foo', 'bar'); -- spi_query_prepared opens a cursor, consumed with spi_fetchrow CREATE FUNCTION prep_alias(int) RETURNS int LANGUAGE plphp AS $$ $plan = spi_prepare('select $1 + 1 as v', 'int4'); $cur = spi_query_prepared($plan, $args[0]); $row = spi_fetchrow($cur); spi_freeplan($plan); return $row['v']; $$; SELECT prep_alias(41); -- Quoting helpers CREATE FUNCTION quoting() RETURNS text LANGUAGE plphp AS $$ $lit = quote_literal("O'Reilly"); $id = quote_ident('weird name'); $nul = quote_nullable(null); $val = quote_nullable('x'); return "$lit | $id | $nul | $val"; $$; SELECT quoting(); -- elog with the various levels CREATE FUNCTION elog_levels() RETURNS void LANGUAGE plphp AS $$ elog('INFO', 'info via elog'); elog('NOTICE', 'notice via elog'); elog('WARNING', 'warning via elog'); $$; SELECT elog_levels(); -- elog ERROR aborts the statement CREATE FUNCTION elog_error() RETURNS void LANGUAGE plphp AS $$ elog('ERROR', 'boom from elog'); $$; SELECT elog_error(); -- A prepared statement with a NULL argument CREATE FUNCTION prep_null() RETURNS text LANGUAGE plphp AS $$ $plan = spi_prepare('select $1::text as v', 'text'); $r = spi_exec_prepared($plan, null); $row = spi_fetch_row($r); spi_freeplan($plan); return $row['v'] === null ? 'null ok' : 'got: ' . $row['v']; $$; SELECT prep_null(); -- A prepared statement with no placeholders CREATE FUNCTION prep_noargs() RETURNS int LANGUAGE plphp AS $$ $plan = spi_prepare('select 7 as v'); $r = spi_exec_prepared($plan); $row = spi_fetch_row($r); spi_freeplan($plan); return intval($row['v']); $$; SELECT prep_noargs(); -- quote_ident only quotes identifiers that need it CREATE FUNCTION quoting2() RETURNS text LANGUAGE plphp AS $$ return quote_ident('simple') . ' | ' . quote_ident('Mixed Case'); $$; SELECT quoting2(); -- elog with an unrecognized level is an error CREATE FUNCTION elog_bad() RETURNS void LANGUAGE plphp AS $$ elog('BOGUS', 'nope'); $$; SELECT elog_bad();