I started new github project - plpgsql_check. It is plpgsql_lint (next generation). plpgsql_lint checked functions on start. plpgsql_check is coming with plpgsql_check_function. You can check any plpgsql function without execution. It can be joined with event trigger and you can ensure a extended check after function creating.
Any comments, patches, ideas are welcome - you can try send me a email or you can join to related postgresql-extensions-hacking google group.
examples:
postgres=# LOAD 'plpgsql'; LOAD postgres=# CREATE EXTENSION plpgsql_check; LOAD postgres=# CREATE TABLE t1(a int, b int); CREATE TABLE postgres=# CREATE OR REPLACE FUNCTION public.f1() RETURNS void LANGUAGE plpgsql AS $function$ DECLARE r record; BEGIN FOR r IN SELECT * FROM t1 LOOP RAISE NOTICE '%', r.c; -- there is bug - table t1 missing "c" column END LOOP; END; $function$; CREATE FUNCTION postgres=# select f1(); -- execution doesn't find a bug due empty table t1 f1 ──── (1 row) postgres=# \x Expanded display is on. postgres=# select * from plpgsql_check_function_tb('f1()'); ─[ RECORD 1 ]─────────────────────────── functionid │ f1 lineno │ 6 statement │ RAISE sqlstate │ 42703 message │ record "r" has no field "c" detail │ [null] hint │ [null] level │ error position │ 0 query │ [null] postgres=# \sf+ f1 CREATE OR REPLACE FUNCTION public.f1() RETURNS void LANGUAGE plpgsql 1 AS $function$ 2 DECLARE r record; 3 BEGIN 4 FOR r IN SELECT * FROM t1 5 LOOP 6 RAISE NOTICE '%', r.c; -- there is bug - table t1 missing "c" column 7 END LOOP; 8 END; 9 $function$ select * from plpgsql_check_function('f1()', fatal_errors := false); plpgsql_check_function ------------------------------------------------------------------------ error:42703:4:SQL statement:column "c" of relation "t1" does not exist Query: update t1 set c = 30 -- ^ error:42P01:7:RAISE:missing FROM-clause entry for table "r" Query: SELECT r.c -- ^ error:42601:7:RAISE:too few parameters specified for RAISE (7 rows) postgres=# select * from plpgsql_check_function('fx()', format:='xml'); plpgsql_check_function ──────────────────────────────────────────────────────────────── <function oid="16400"> ↵ <issue> ↵ <level>error</level> ↵ <sqlstate>42P01</Sqlstate> ↵ <message>relation "foo111" does not exist</Message> ↵ <stmt lineno="3">RETURN</Stmt> ↵ <query position="23">SELECT (select a from foo111)</Query>↵ </Issue> ↵ </Function> (1 row)
This is really cool! I've been working on a similar tool, but never managed to get anything usable out.
ReplyDeleteWould you mind getting pull requests on github? I find that easier to work with than sending patches over email.
With community involvement for some active and serious development, It can be extended to be very very useful tool.
ReplyDeleteWell done & Thanks for sharing.
@Marko, Denish - I welcome any patches, ideas, bugreports, ports to other o.s. - pull request are most user friendly.
ReplyDeleteI opened a google group for communication about development of this and other extensions https://groups.google.com/forum/?hl=en#!forum/postgresql-extensions-hacking
This is really a useful feature for user's of plpgsql and I really hope that we can get this into core soon. I had even recommended your patch to some people who needed this feature urgently sometime back.
ReplyDelete