2014-09-05 9:52 GMT+02:00 Marko Tiikkaja <ma...@joh.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
>

Reply via email to