proposal: plpgsql - Assert statement - Mailing list pgsql-hackers

From Pavel Stehule
Subject proposal: plpgsql - Assert statement
Date
Msg-id CAFj8pRDiWaACoHQwYbBn_YuW2UxpWFd1Y4o2XF5BO-zHNmfRaA@mail.gmail.com
Whole thread Raw
Responses Re: proposal: plpgsql - Assert statement
Re: proposal: plpgsql - Assert statement
List pgsql-hackers
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.

pgsql-hackers by date:

Previous
From: Vladimir Romanov
Date:
Subject: ODBC Driver performance comparison
Next
From: Jeevan Chalke
Date:
Subject: Re: Re: proposal: ignore null fields in not relation type composite type based constructors