create or replace function test_spi_1(int) returns int language plphp as $$ $query = "select generate_series(1, $args[0])"; $result = spi_exec($query); $msg = "processed: " . spi_processed($result) . " "; $msg .= "status: " . spi_status($result); pg_raise('notice', $msg); $a = 0; while ($row = spi_fetch_row($result)) $a += $row['generate_series']; pg_raise('notice', "total sum is " . $a); return intval($a); $$; select test_spi_1(1); select test_spi_1(5); select test_spi_1(100); create or replace function test_spi_2() returns int language plphp as $$ $ret = 0; $query = "select 1 as a union all select 2"; $res1 = spi_exec($query); $query = "select 3 as b union all select 4"; $res2 = spi_exec($query); while ($r1 = spi_fetch_row($res1)) { spi_rewind($res2); while ($r2 = spi_fetch_row($res2)) { $msg = sprintf("got values %d and %d", $r1['a'], $r2['b']); pg_raise('notice', $msg); $ret += $r1['a'] * $r2['b']; } } return $ret; $$; -- 1 * 3 + 1 * 4 + 2 * 3 + 2 * 4 = 21 select test_spi_2(); create function test_spi_limit() returns int language plphp as $$ $ret = 0; $query = "select 1 as a union all select 2 union all select 3"; $res = spi_exec($query, 2); while ($r = spi_fetch_row($res)) { pg_raise('notice', "got value " . $r['a']); $ret += $r['a']; } return $ret; $$; -- 1 + 2 = 3 select test_spi_limit(); create function div_by_zero(int[], int) returns int language plphp as $$ $ret = 0; $divisor = $args[1]; foreach ($args[0] as $v) { $query = "select $v::float / $divisor as division"; $res = spi_exec($query); while ($r = spi_fetch_row($res)) { pg_raise('notice', sprintf("got value %f", $r['division'])); $ret += $r['division']; } } return intval($ret); $$; -- test that a function can continue to be executed after it has raised -- an error -- 1/1 + 2/1 + 3/1 = 6 select div_by_zero('{1,2,3}', 1); -- oops, division by zero select div_by_zero('{1,2,3}', 0); -- 1/2 + 2/2 + 3/2 = 3 select div_by_zero('{1,2,3}', 2);