I have a function test:
CREATE OR REPLACE FUNCTION public.test()
RETURNS void
LANGUAGE plpgsql
AS $function$
DECLARE r record;
BEGIN
BEGIN
DELETE FROM foo; -- temp table
EXCEPTION WHEN OTHERS THEN
CREATE TEMP TABLE foo(a int, b int);
END;
INSERT INTO foo VALUES(10,20);
FOR r IN SELECT * FROM foo
LOOP
RAISE NOTICE '% %', r.a, r.b;
END LOOP;
END;
$function$
This code I cannot to verify with plpgsql_check due dependency on temp table foo:postgres=# select plpgsql_check_function('test()', fatal_errors := false);
plpgsql_check_function
----------------------------------------------------------------------------
error:42P01:5:SQL statement:relation "foo" does not exist
Query: DELETE FROM foo
-- ^
error:42P01:9:SQL statement:relation "foo" does not exist
Query: INSERT INTO foo VALUES(10,20)
-- ^
error:42P01:10:FOR over SELECT rows:relation "foo" does not exist
Query: SELECT * FROM foo
-- ^
error:55000:12:RAISE:record "r" is not assigned yet
Detail: The tuple structure of a not-yet-assigned record is indeterminate.
Context: SQL statement "SELECT r.a"
error:55000:12:RAISE:record "r" is not assigned yet
Detail: The tuple structure of a not-yet-assigned record is indeterminate.
Context: SQL statement "SELECT r.b"
(15 rows)
I can create persistent table foo. But if I forgot to drop this table, I can have lot of problems, but some one can be invisible. So I created "template storage" that disallow any DML or SELECT. This decrease a risk and I can have these fake tables persistent:
CREATE SERVER template FOREIGN DATA WRAPPER template_fdw;
CREATE FOREIGN TABLE foo(a int, b int) SERVER template;
postgres=# SELECT * FROM foo;
ERROR: cannot read from table "public.foo"
DETAIL: Table is template.
HINT: Create temp table by statement "CREATE TEMP TABLE foo(LIKE public.foo INCLUDING ALL);"
-- but EXPLAIN is valid
postgres=# EXPLAIN SELECT * FROM foo;
QUERY PLAN
-------------------------------------------------------
Foreign Scan on foo (cost=0.00..0.00 rows=0 width=8)
(1 row)
-- and now I can do static validation
postgres=# select plpgsql_check_function('test()', fatal_errors := false);
plpgsql_check_function
------------------------
(0 rows)
No comments:
Post a Comment