Hello
Assert is usually implemented as custom functions and used via PERFORM
statement now
-- usual current solution
PERFORM Assert(some expression)
I would to implement Assert as plpgsql internal statement due bigger
possibilities to design syntax and internal implementation now and in
future. More - as plpgsql statement should be compatible with any current
code - because there should not be collision between SQL and PLpgSQL space.
So this design doesn't break any current code.
I propose following syntax with following ecosystem:
ASSERT [ NOTICE, WARNING, >>EXCEPTION<< ]
[ string expression or literal - explicit message ]
[ USING clause - same as RAISE stmt (possible in future ) ]
( ROW_COUNT ( = | <> ) ( 1 | 0 ) |
( QUERY some query should not be empty ) |
( CHECK some expression should be true )
( IS NOT NULL expression should not be null )
Every variant (ROW_COUNT, QUERY, CHECK, IS NOT NULL) has own default message
These asserts can be controlled by set of options (by default asserts are
enabled):
#option asserts_disable
#option asserts_disable_notice .. don't check thin asserts
#option asserts_not_stop .. raise warning instead exception
some examples:
UPDATE tab SET c = 1 WHERE pk = somevar;
ASSERT ROW_COUNT = 1; -- knows what is previous DML or Dynamic DML
ASSERT CHECK a < 100;
ASSERT IS NOT NULL pk;
ASSERT QUERY SELECT id FROM tab WHERE x = 1;
ASSERT CHECK 2 = (SELECT count(*) FROM tab WHERE x = 1);
ASSERT WARNING "data are there" QUERY SELECT ...
Shorter variant should to work
CREATE OR REPLACE FUNCTION assert(boolean)
RETURNS void AS $$
BEGIN
ASSERT CHECK $1;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION assert(boolean, text)
RETURNS void AS $$
BEGIN
ASSERT $1 CHECK $2;
END;
$$ LANGUAGE plpgsql;
Usage:
PERFORM assert(a <> 10);
PERFORM assert(a <> 10, "a should be 10");
Comments, notices?
Regards
Pavel
This design should not break any current solution, it allows a static
analyses, and it doesn't close a door for future enhancing.