Question

This pgTAP test

BEGIN;

CREATE OR REPLACE FUNCTION test.testXUnitStyle() RETURNS SETOF TEXT AS $$
    SELECT ok(4 * 5 = 20, 'math should work in postgres');
$$ LANGUAGE plpgsql;

SELECT * FROM runtests('test'::name);

gives me this syntax error:

prove --ext .sql t/pgtap-xunit.sql  --source pgTAP --pgtap-option dbname=test
psql:t/pgtap-xunit.sql:5: ERROR:  syntax error at or near "SELECT"
LINE 2:     SELECT ok(4 * 5 = 20, 'math should work in postgres');
            ^
t/pgtap-xunit.sql .. Dubious, test returned 3 (wstat 768, 0x300)
No subtests run

Test Summary Report
-------------------
t/pgtap-xunit.sql (Wstat: 768 Tests: 0 Failed: 0)
  Non-zero exit status: 3
  Parse errors: No plan found in TAP output
Files=1, Tests=0,  0 wallclock secs ( 0.03 usr +  0.00 sys =  0.03 CPU)
Result: FAIL

but if I change the LANGUAGE plpgsql to just LANGUAGE sql it works.

What do I need to do to run the test as plpgsql?

Was it helpful?

Solution

PL/PgSQL has a different structure. You can't just copy an SQL function body, declare it language plpgsql, and expect it to work.

Run this standalone and you'll see:

regress=> CREATE SCHEMA test;
CREATE SCHEMA
regress=> CREATE OR REPLACE FUNCTION test.testXUnitStyle() RETURNS SETOF TEXT AS $$
    SELECT ok(4 * 5 = 20, 'math should work in postgres');
$$ LANGUAGE plpgsql;
ERROR:  syntax error at or near "SELECT"
LINE 2:     SELECT ok(4 * 5 = 20, 'math should work in postgres');
            ^

If you read the manual for Pl/PgSQL you'll quickly understand why: PL/PgSQL has overall struture of [DECLARE ...] BEGIN ... END;. You must also use PERFORM to run a query and discard the result, or RETURN QUERY if you wish to return the result. So you'd rewrite your code in PL/PgSQL as:

CREATE OR REPLACE FUNCTION test.testXUnitStyle() RETURNS SETOF TEXT AS $$
BEGIN
    RETURN QUERY SELECT ok(4 * 5 = 20, 'math should work in postgres');
END;
$$ LANGUAGE plpgsql;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top