Re: proposal: plpgsql - Assert statement

From: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
To: Marko Tiikkaja <marko(at)joh(dot)to>
Cc: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: proposal: plpgsql - Assert statement
Date: 2014-09-05 08:09:23
Message-ID: CAFj8pRAOyLY1sZdA-QMQ5cfeehoq_bu6e495xK==wTvmN7=vag@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

2014-09-05 9:52 GMT+02:00 Marko Tiikkaja <marko(at)joh(dot)to>:

> On 2014-09-05 08:16, Pavel Stehule wrote:
>
>> 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.
>>
>
> It does require making ASSERT an unreserved keyword, no? That would break
> code where someone used "assert" as a variable name, for example.
>

sure, sorry

>
> 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 )
>>
>
> 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);
>>
>
> I don't see the need for specialized syntax. If the syntax was just
> ASSERT (<expr>), these could be written as:
>
> ASSERT (row_count = 1); -- assuming we provide a special variable instead
> of having to do GET DIAGNOSTICS
> ASSERT (a < 100); -- or perhaps ASSERT((a < 100) IS TRUE); depending on
> how NULLs are handled
> ASSERT (pk IS NOT NULL);
> ASSERT (EXISTS(SELECT id FROM tab WHERE x = 1));
> ASSERT (2 = (SELECT count(*) FROM tab WHERE x = 1));
>

I disagree. Your design is expression based design with following
disadvantages:

a) there is only one possible default message -- "Assertation fault"

b) there is not possibility to show statement for ASSERT ROW_COUNT

c) any static analyse is blocked, because there is not clean semantic

d) In PLpgSQL language a syntax STATEMENT '(' expression ')' is new - there
is nothing yet --- it is discuss from yesterday -- still I am speaking
about plpgsql -- I don't would to refactor plpgsql parser.

e) for your proposal we don't need any special - you can do it as custom
function - then there is no sense to define it. Maximally it can live as
some extension in some shared repository

>
> the idea being that it gets turned into SELECT <expr>; and then
> evaluated.
>
> ASSERT WARNING "data are there" QUERY SELECT ...
>>
>
> I think this could still be parsed correctly, though I'm not 100% sure on
> that:
>
> ASSERT WARNING (EXISTS(SELECT ..)), 'data are there';
>

PLpgSQL uses a ';' or some plpgsql keyword as SQL statement delimiter. It
reason why RETURN QUERY ... ';' So in this case can practical to place SQL
statement on the end of plpgsql statement.

parenthesis are not practical, because it is hard to identify bug ..

A simplicity of integration SQL and PLpgSQL is in using "smart" keywords -
It is more verbose, and it allow to well diagnostics

>
> For extra points the error detail could work similarly to
> print_strict_params. e.g. ASSERT(row_count = 1); would display the value
> of row_count in the DETAIL line, since row_count was a parameter to the
> expression.
>
>
>
> .marko
>

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message didier 2014-09-05 08:17:29 Re: postgresql latency & bgwriter not doing its job
Previous Message Marko Tiikkaja 2014-09-05 07:52:04 Re: proposal: plpgsql - Assert statement