proposal: plpgsql - Assert statement

Started by Pavel Stehuleover 11 years ago94 messageshackers
Jump to latest
#1Pavel Stehule
pavel.stehule@gmail.com

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.

#2Marko Tiikkaja
marko@joh.to
In reply to: Pavel Stehule (#1)
Re: proposal: plpgsql - Assert statement

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.

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));

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';

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

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Pavel Stehule
pavel.stehule@gmail.com
In reply to: Marko Tiikkaja (#2)
Re: proposal: plpgsql - Assert statement

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

Show quoted text

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

#4Marko Tiikkaja
marko@joh.to
In reply to: Pavel Stehule (#3)
Re: proposal: plpgsql - Assert statement

On 9/5/14 10:09 AM, Pavel Stehule wrote:

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.

*shrug* There are lots of cases where a comma is used as well, e.g.
RAISE NOTICE '..', <expr>, <expr>;

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

I don't see why. The PL/PgSQL SQL parser goes to great lengths to
identify unmatched parenthesis. But the parens probably aren't
necessary in the first place; you could just omit them and keep parsing
until the next comma AFAICT. So the syntax would be:

RAISE [ NOTICE | WARNING | EXCEPTION/ASSERT/WHATEVER ]
boolean_expr [, error_message [, error_message_param [, ... ] ] ];

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

I disagree. The new keywords provide nothing of value here. They even
encourage the use of quirky syntax in *exchange* for verbosity ("IS NOT
NULL pk"? really?).

.marko

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Pavel Stehule
pavel.stehule@gmail.com
In reply to: Marko Tiikkaja (#4)
Re: proposal: plpgsql - Assert statement

2014-09-05 10:33 GMT+02:00 Marko Tiikkaja <marko@joh.to>:

On 9/5/14 10:09 AM, Pavel Stehule wrote:

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.

*shrug* There are lots of cases where a comma is used as well, e.g. RAISE
NOTICE '..', <expr>, <expr>;

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

I don't see why. The PL/PgSQL SQL parser goes to great lengths to
identify unmatched parenthesis. But the parens probably aren't necessary
in the first place; you could just omit them and keep parsing until the
next comma AFAICT. So the syntax would be:

RAISE [ NOTICE | WARNING | EXCEPTION/ASSERT/WHATEVER ]
boolean_expr [, error_message [, error_message_param [, ... ] ] ];

extension RAISE about ASSERT level has minimal new value

A simplicity of integration SQL and PLpgSQL is in using "smart" keywords -

It is more verbose, and it allow to well diagnostics

I disagree. The new keywords provide nothing of value here. They even
encourage the use of quirky syntax in *exchange* for verbosity ("IS NOT
NULL pk"? really?).

It is about semantic and conformity of proposed tools. Sure, all can
reduced to ASSERT(expr) .. but where is some benefit against function call

I am able to do without any change of language as plpgsql extension - there
is no necessary to do any change for too thin proposal

Show quoted text

.marko

#6Marko Tiikkaja
marko@joh.to
In reply to: Pavel Stehule (#5)
Re: proposal: plpgsql - Assert statement

On 9/5/14 10:40 AM, Pavel Stehule wrote:

2014-09-05 10:33 GMT+02:00 Marko Tiikkaja <marko@joh.to>:

I don't see why. The PL/PgSQL SQL parser goes to great lengths to
identify unmatched parenthesis. But the parens probably aren't necessary
in the first place; you could just omit them and keep parsing until the
next comma AFAICT. So the syntax would be:

RAISE [ NOTICE | WARNING | EXCEPTION/ASSERT/WHATEVER ]
boolean_expr [, error_message [, error_message_param [, ... ] ] ];

extension RAISE about ASSERT level has minimal new value

Oops. I meant to type ASSERT there, instead of RAISE. Does that make
more sense?

I disagree. The new keywords provide nothing of value here. They even
encourage the use of quirky syntax in *exchange* for verbosity ("IS NOT
NULL pk"? really?).

It is about semantic and conformity of proposed tools. Sure, all can
reduced to ASSERT(expr) .. but where is some benefit against function call

I see several benefits:

1) Standard syntax, available anywhere
2) Since the RAISE EXCEPTION happens at the caller's site, we can
provide information not available to an ordinary function, such as the
values of the parameters passed to it
3) We can make the exception uncatchable
4) ASSERTs can be easily disabled (if we choose to allow that), even
per-function

I am able to do without any change of language as plpgsql extension - there
is no necessary to do any change for too thin proposal

What *exactly* about my proposal is "too thin"? What does your thing do
that mine doesn't? If you're saying your suggestion allows us to give a
better error message, I disagree:

( ROW_COUNT ( = | <> ) ( 1 | 0 ) |

I've already addressed this: we can print the parameters and their
values automatically, so printing the row count here doesn't give any
additional value.

( QUERY some query should not be empty ) |

With this definition, absolutely zero value over ASSERT EXISTS(..);

( CHECK some expression should be true )

No additional value; it's either NULL, FALSE or TRUE and both syntaxes
can display what the expression evaluated to.

( IS NOT NULL expression should not be null )

It's either NULL or it isn't. No additional value.

.marko

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Pavel Stehule
pavel.stehule@gmail.com
In reply to: Marko Tiikkaja (#6)
Re: proposal: plpgsql - Assert statement

2014-09-05 10:57 GMT+02:00 Marko Tiikkaja <marko@joh.to>:

On 9/5/14 10:40 AM, Pavel Stehule wrote:

2014-09-05 10:33 GMT+02:00 Marko Tiikkaja <marko@joh.to>:

I don't see why. The PL/PgSQL SQL parser goes to great lengths to
identify unmatched parenthesis. But the parens probably aren't necessary
in the first place; you could just omit them and keep parsing until the
next comma AFAICT. So the syntax would be:

RAISE [ NOTICE | WARNING | EXCEPTION/ASSERT/WHATEVER ]
boolean_expr [, error_message [, error_message_param [, ... ] ] ];

extension RAISE about ASSERT level has minimal new value

Oops. I meant to type ASSERT there, instead of RAISE. Does that make
more sense?

for me a basic limit is boolean_expr

I disagree. The new keywords provide nothing of value here. They even

encourage the use of quirky syntax in *exchange* for verbosity ("IS NOT
NULL pk"? really?).

It is about semantic and conformity of proposed tools. Sure, all can
reduced to ASSERT(expr) .. but where is some benefit against function call

I see several benefits:

1) Standard syntax, available anywhere
2) Since the RAISE EXCEPTION happens at the caller's site, we can
provide information not available to an ordinary function, such as the
values of the parameters passed to it
3) We can make the exception uncatchable
4) ASSERTs can be easily disabled (if we choose to allow that), even
per-function

All points can be solved by extension on PGXN .. and your proposed syntax
can be better processed on Postgres level than PLpgSQL level.

I am able to do without any change of language as plpgsql extension -

there
is no necessary to do any change for too thin proposal

What *exactly* about my proposal is "too thin"? What does your thing do
that mine doesn't? If you're saying your suggestion allows us to give a
better error message, I disagree:

"Too thin" it means so there is not possibility to extensibility,
possibility to define dafaults, possibility to use it for static analyse.

( ROW_COUNT ( = | <> ) ( 1 | 0 ) |

I've already addressed this: we can print the parameters and their values
automatically, so printing the row count here doesn't give any additional
value.

In this case, I can use a plpgsql parser for static analyse - I can do
warning, if related query has not filter PK and similar.

Show quoted text

( QUERY some query should not be empty ) |

With this definition, absolutely zero value over ASSERT EXISTS(..);

( CHECK some expression should be true )

No additional value; it's either NULL, FALSE or TRUE and both syntaxes can
display what the expression evaluated to.

( IS NOT NULL expression should not be null )

It's either NULL or it isn't. No additional value.

.marko

#8Marko Tiikkaja
marko@joh.to
In reply to: Pavel Stehule (#7)
Re: proposal: plpgsql - Assert statement

On 9/5/14 11:08 AM, Pavel Stehule wrote:

2014-09-05 10:57 GMT+02:00 Marko Tiikkaja <marko@joh.to>:

Oops. I meant to type ASSERT there, instead of RAISE. Does that make
more sense?

for me a basic limit is boolean_expr

I don't understand what you mean by this.

It is about semantic and conformity of proposed tools. Sure, all can
reduced to ASSERT(expr) .. but where is some benefit against function call

I see several benefits:

1) Standard syntax, available anywhere
2) Since the RAISE EXCEPTION happens at the caller's site, we can
provide information not available to an ordinary function, such as the
values of the parameters passed to it
3) We can make the exception uncatchable
4) ASSERTs can be easily disabled (if we choose to allow that), even
per-function

All points can be solved by extension on PGXN ..

#3 probably. Being able to satisfy #1 through PGXN is ridiculous. #2
and #4 would require at least hooking into PL/PgSQL, which might be
possible, but it's intrusive and honestly feels fragile.

But perhaps more to the point, why would that criticism apply to my
suggestion, but not yours? Why don't we just reject any ASSERT syntax?

and your proposed syntax
can be better processed on Postgres level than PLpgSQL level.

*shrug* Doing it in SQL would probably break more stuff. I'm trying to
contain the damage. And arguably, this is mostly only useful in PL/PgSQL.

I am able to do without any change of language as plpgsql extension -

there
is no necessary to do any change for too thin proposal

What *exactly* about my proposal is "too thin"? What does your thing do
that mine doesn't? If you're saying your suggestion allows us to give a
better error message, I disagree:

"Too thin" it means so there is not possibility to extensibility,
possibility to define dafaults, possibility to use it for static analyse.

Again, why does this criticism only apply to my suggestion and not yours?

( ROW_COUNT ( = | <> ) ( 1 | 0 ) |

I've already addressed this: we can print the parameters and their values
automatically, so printing the row count here doesn't give any additional
value.

In this case, I can use a plpgsql parser for static analyse - I can do
warning, if related query has not filter PK and similar.

You can do that anyway, you just need to work a bit harder. I don't see
the problem, really.

.marko

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Pavel Stehule
pavel.stehule@gmail.com
In reply to: Marko Tiikkaja (#8)
Re: proposal: plpgsql - Assert statement

2014-09-05 11:17 GMT+02:00 Marko Tiikkaja <marko@joh.to>:

On 9/5/14 11:08 AM, Pavel Stehule wrote:

2014-09-05 10:57 GMT+02:00 Marko Tiikkaja <marko@joh.to>:

Oops. I meant to type ASSERT there, instead of RAISE. Does that make
more sense?

for me a basic limit is boolean_expr

I don't understand what you mean by this.

It is about semantic and conformity of proposed tools. Sure, all can

reduced to ASSERT(expr) .. but where is some benefit against function
call

I see several benefits:

1) Standard syntax, available anywhere
2) Since the RAISE EXCEPTION happens at the caller's site, we can
provide information not available to an ordinary function, such as the
values of the parameters passed to it
3) We can make the exception uncatchable
4) ASSERTs can be easily disabled (if we choose to allow that), even
per-function

All points can be solved by extension on PGXN ..

#3 probably. Being able to satisfy #1 through PGXN is ridiculous. #2 and
#4 would require at least hooking into PL/PgSQL, which might be possible,
but it's intrusive and honestly feels fragile.

But perhaps more to the point, why would that criticism apply to my
suggestion, but not yours? Why don't we just reject any ASSERT syntax?

and your proposed syntax

can be better processed on Postgres level than PLpgSQL level.

*shrug* Doing it in SQL would probably break more stuff. I'm trying to
contain the damage. And arguably, this is mostly only useful in PL/PgSQL.

I am able to do without any change of language as plpgsql extension -

there
is no necessary to do any change for too thin proposal

What *exactly* about my proposal is "too thin"? What does your thing do
that mine doesn't? If you're saying your suggestion allows us to give a
better error message, I disagree:

"Too thin" it means so there is not possibility to extensibility,
possibility to define dafaults, possibility to use it for static analyse.

Again, why does this criticism only apply to my suggestion and not yours?

There is one stronger difference - there is clean, what is targer of
assertation, because there is defined semantic.

When all is just any expression, there is nothing specified semantic

( ROW_COUNT ( = | <> ) ( 1 | 0 ) |

I've already addressed this: we can print the parameters and their values
automatically, so printing the row count here doesn't give any additional
value.

In this case, I can use a plpgsql parser for static analyse - I can do
warning, if related query has not filter PK and similar.

You can do that anyway, you just need to work a bit harder. I don't see
the problem, really.

bit harder, with possibility to false identification

Show quoted text

.marko

#10Jan Wieck
JanWieck@Yahoo.com
In reply to: Pavel Stehule (#5)
Re: proposal: plpgsql - Assert statement

On 09/05/2014 04:40 AM, Pavel Stehule wrote:

2014-09-05 10:33 GMT+02:00 Marko Tiikkaja <marko@joh.to
<mailto:marko@joh.to>>:

On 9/5/14 10:09 AM, Pavel Stehule wrote:

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.

*shrug* There are lots of cases where a comma is used as well, e.g.
RAISE NOTICE '..', <expr>, <expr>;

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

I don't see why. The PL/PgSQL SQL parser goes to great lengths to
identify unmatched parenthesis. But the parens probably aren't
necessary in the first place; you could just omit them and keep
parsing until the next comma AFAICT. So the syntax would be:

RAISE [ NOTICE | WARNING | EXCEPTION/ASSERT/WHATEVER ]
boolean_expr [, error_message [, error_message_param [, ... ] ] ];

extension RAISE about ASSERT level has minimal new value

Adding a WHEN clause to RAISE would have the benefit of not needing any
new keywords at all.

RAISE EXCEPTION 'format' [, expr ...] WHEN row_count <> 1;

Regards,
Jan

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

I disagree. The new keywords provide nothing of value here. They
even encourage the use of quirky syntax in *exchange* for verbosity
("IS NOT NULL pk"? really?).

It is about semantic and conformity of proposed tools. Sure, all can
reduced to ASSERT(expr) .. but where is some benefit against function call

I am able to do without any change of language as plpgsql extension -
there is no necessary to do any change for too thin proposal

.marko

--
Jan Wieck
Senior Software Engineer
http://slony.info

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Pavel Stehule
pavel.stehule@gmail.com
In reply to: Jan Wieck (#10)
Re: proposal: plpgsql - Assert statement

2014-09-05 14:35 GMT+02:00 Jan Wieck <jan@wi3ck.info>:

On 09/05/2014 04:40 AM, Pavel Stehule wrote:

2014-09-05 10:33 GMT+02:00 Marko Tiikkaja <marko@joh.to
<mailto:marko@joh.to>>:

On 9/5/14 10:09 AM, Pavel Stehule wrote:

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.

*shrug* There are lots of cases where a comma is used as well, e.g.
RAISE NOTICE '..', <expr>, <expr>;

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

I don't see why. The PL/PgSQL SQL parser goes to great lengths to
identify unmatched parenthesis. But the parens probably aren't
necessary in the first place; you could just omit them and keep
parsing until the next comma AFAICT. So the syntax would be:

RAISE [ NOTICE | WARNING | EXCEPTION/ASSERT/WHATEVER ]
boolean_expr [, error_message [, error_message_param [, ... ] ] ];

extension RAISE about ASSERT level has minimal new value

Adding a WHEN clause to RAISE would have the benefit of not needing any
new keywords at all.

RAISE EXCEPTION 'format' [, expr ...] WHEN row_count <> 1;

It was one my older proposal.

Can we find a agreement there?

Pavel

Show quoted text

Regards,
Jan

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

I disagree. The new keywords provide nothing of value here. They
even encourage the use of quirky syntax in *exchange* for verbosity
("IS NOT NULL pk"? really?).

It is about semantic and conformity of proposed tools. Sure, all can
reduced to ASSERT(expr) .. but where is some benefit against function call

I am able to do without any change of language as plpgsql extension -
there is no necessary to do any change for too thin proposal

.marko

--
Jan Wieck
Senior Software Engineer
http://slony.info

#12Petr Jelinek
petr@2ndquadrant.com
In reply to: Jan Wieck (#10)
Re: proposal: plpgsql - Assert statement

On 05/09/14 14:35, Jan Wieck wrote:

On 09/05/2014 04:40 AM, Pavel Stehule wrote:

Adding a WHEN clause to RAISE would have the benefit of not needing any
new keywords at all.

RAISE EXCEPTION 'format' [, expr ...] WHEN row_count <> 1;

+1

--
Petr Jelinek http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#13Marko Tiikkaja
marko@joh.to
In reply to: Pavel Stehule (#11)
Re: proposal: plpgsql - Assert statement

On 2014-09-06 7:27 AM, Pavel Stehule wrote:

2014-09-05 14:35 GMT+02:00 Jan Wieck <jan@wi3ck.info>:

Adding a WHEN clause to RAISE would have the benefit of not needing any
new keywords at all.

RAISE EXCEPTION 'format' [, expr ...] WHEN row_count <> 1;

It was one my older proposal.

Can we find a agreement there?

I find:

1) The syntax less readable than IF row_count <> 1 THEN RAISE
EXCEPTION ..; END IF;
2) It needless to require the user to specify an error message for
every assertion.
3) Allowing these to be disabled would be weird (though I might be
the only one who wants that feature at this point).
4) It would also be weird to display the parameters passed to the
WHEN clause like I suggested here:
/messages/by-id/54096BA4.5030600@joh.to . I think
that's a crucial part of the feature.

So at least the vote isn't unanimous: -1 from me.

.marko

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#14Pavel Stehule
pavel.stehule@gmail.com
In reply to: Marko Tiikkaja (#13)
Re: proposal: plpgsql - Assert statement

2014-09-06 19:26 GMT+02:00 Marko Tiikkaja <marko@joh.to>:

On 2014-09-06 7:27 AM, Pavel Stehule wrote:

2014-09-05 14:35 GMT+02:00 Jan Wieck <jan@wi3ck.info>:

Adding a WHEN clause to RAISE would have the benefit of not needing any
new keywords at all.

RAISE EXCEPTION 'format' [, expr ...] WHEN row_count <> 1;

It was one my older proposal.

Can we find a agreement there?

I find:

1) The syntax less readable than IF row_count <> 1 THEN RAISE EXCEPTION
..; END IF;
2) It needless to require the user to specify an error message for every
assertion.
3) Allowing these to be disabled would be weird (though I might be the
only one who wants that feature at this point).
4) It would also be weird to display the parameters passed to the WHEN
clause like I suggested here: http://www.postgresql.org/
message-id/54096BA4.5030600@joh.to . I think that's a crucial part of
the feature.

So at least the vote isn't unanimous: -1 from me.

this doesn't to supply assertions, it is just shorter form

Pavel

Show quoted text

.marko

#15Marko Tiikkaja
marko@joh.to
In reply to: Pavel Stehule (#14)
Re: proposal: plpgsql - Assert statement

On 2014-09-06 7:49 PM, Pavel Stehule wrote:

this doesn't to supply assertions, it is just shorter form

The original proposal very clearly seems to be "why don't we do this
*instead* of assertions?" And in that case all of my points apply, and
I'm very much against this syntax. If this is supposed to be in the
language *in addition to* assertions, let's please be clear about that.
(In that case I wouldn't object, though I probably wouldn't use this
feature either.)

.marko

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#16Pavel Stehule
pavel.stehule@gmail.com
In reply to: Marko Tiikkaja (#15)
Re: proposal: plpgsql - Assert statement

2014-09-06 19:59 GMT+02:00 Marko Tiikkaja <marko@joh.to>:

On 2014-09-06 7:49 PM, Pavel Stehule wrote:

this doesn't to supply assertions, it is just shorter form

The original proposal very clearly seems to be "why don't we do this
*instead* of assertions?" And in that case all of my points apply, and I'm
very much against this syntax. If this is supposed to be in the language
*in addition to* assertions, let's please be clear about that. (In that
case I wouldn't object, though I probably wouldn't use this feature either.)

It was just my reaction to Jan proposal in this thread.

pavel

Show quoted text

.marko

#17Robert Haas
robertmhaas@gmail.com
In reply to: Pavel Stehule (#1)
Re: proposal: plpgsql - Assert statement

On Fri, Sep 5, 2014 at 2:16 AM, Pavel Stehule <pavel.stehule@gmail.com> 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.

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

That's probably not the ugliest syntax I've *ever* seen, but it's
definitely the ugliest syntax I've seen today.

I previously proposed RAISE ASSERT ... WHERE, which seems like a nice
variant of what we've already got, but perhaps this whole discussion
merely illustrates that it's hard to get more than 1 vote for any
proposal in this area.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#18Craig Ringer
craig@2ndquadrant.com
In reply to: Pavel Stehule (#9)
Re: proposal: plpgsql - Assert statement

On 09/05/2014 05:21 PM, Pavel Stehule wrote:

*shrug* Doing it in SQL would probably break more stuff. I'm trying to
contain the damage. And arguably, this is mostly only useful in PL/PgSQL.

I've wanted assertions in SQL enough that I often write trivial wrappers
around `raise` in PL/PgSQL for use in `CASE` statements etc.

--
Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#19Craig Ringer
craig@2ndquadrant.com
In reply to: Robert Haas (#17)
Re: proposal: plpgsql - Assert statement

On 09/09/2014 05:20 AM, Robert Haas wrote:

I previously proposed RAISE ASSERT ... WHERE, which seems like a nice
variant of what we've already got, but perhaps this whole discussion
merely illustrates that it's hard to get more than 1 vote for any
proposal in this area.

Well, you have Petr's for RAISE EXCEPTION ... WHEN, and I'd also like
that or RAISE ASSERT ... WHEN.

Much (much) saner than the other proposals on this thread IMO.

--
Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#20Marko Tiikkaja
marko@joh.to
In reply to: Craig Ringer (#18)
Re: proposal: plpgsql - Assert statement

On 2014-09-09 07:54, Craig Ringer wrote:

On 09/05/2014 05:21 PM, Pavel Stehule wrote:

*shrug* Doing it in SQL would probably break more stuff. I'm trying to
contain the damage. And arguably, this is mostly only useful in PL/PgSQL.

I've wanted assertions in SQL enough that I often write trivial wrappers
around `raise` in PL/PgSQL for use in `CASE` statements etc.

Yeah, as have I. I've also advocated that there should be a
raise_exception(text, anyelement) anyelement function shipped with
postgres.

But this is something different; this is just a single statement which
asserts that some expression evaluates to true. Even if we allowed it
to be used as a scalar expression, there's still the problem anyelement
is commonly used to work around.

.marko

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#21Pavel Stehule
pavel.stehule@gmail.com
In reply to: Craig Ringer (#19)
#22Pavel Stehule
pavel.stehule@gmail.com
In reply to: Craig Ringer (#18)
#23Jan Wieck
JanWieck@Yahoo.com
In reply to: Pavel Stehule (#22)
#24Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Jan Wieck (#23)
#25Peter Eisentraut
peter_e@gmx.net
In reply to: Alvaro Herrera (#24)
#26Peter Eisentraut
peter_e@gmx.net
In reply to: Jan Wieck (#23)
#27Marko Tiikkaja
marko@joh.to
In reply to: Peter Eisentraut (#26)
#28Pavel Stehule
pavel.stehule@gmail.com
In reply to: Peter Eisentraut (#26)
#29Peter Eisentraut
peter_e@gmx.net
In reply to: Pavel Stehule (#28)
#30Pavel Stehule
pavel.stehule@gmail.com
In reply to: Peter Eisentraut (#29)
#31Jan Wieck
JanWieck@Yahoo.com
In reply to: Peter Eisentraut (#29)
#32Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Jan Wieck (#31)
#33Petr Jelinek
petr@2ndquadrant.com
In reply to: Pavel Stehule (#21)
#34Ali Akbar
the.apaan@gmail.com
In reply to: Jim Nasby (#32)
#35Pavel Stehule
pavel.stehule@gmail.com
In reply to: Ali Akbar (#34)
#36Pavel Stehule
pavel.stehule@gmail.com
In reply to: Petr Jelinek (#33)
#37Petr Jelinek
petr@2ndquadrant.com
In reply to: Pavel Stehule (#36)
#38Pavel Stehule
pavel.stehule@gmail.com
In reply to: Petr Jelinek (#37)
#39Simon Riggs
simon@2ndQuadrant.com
In reply to: Pavel Stehule (#38)
#40Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Simon Riggs (#39)
#41Pavel Stehule
pavel.stehule@gmail.com
In reply to: Simon Riggs (#39)
#42Simon Riggs
simon@2ndQuadrant.com
In reply to: Jim Nasby (#40)
#43Pavel Stehule
pavel.stehule@gmail.com
In reply to: Simon Riggs (#42)
#44Andrew Dunstan
andrew@dunslane.net
In reply to: Simon Riggs (#42)
#45Simon Riggs
simon@2ndQuadrant.com
In reply to: Pavel Stehule (#43)
#46Pavel Stehule
pavel.stehule@gmail.com
In reply to: Simon Riggs (#45)
#47Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Andrew Dunstan (#44)
#48Andrew Dunstan
andrew@dunslane.net
In reply to: Jim Nasby (#47)
#49Pavel Stehule
pavel.stehule@gmail.com
In reply to: Andrew Dunstan (#48)
#50Petr Jelinek
petr@2ndquadrant.com
In reply to: Pavel Stehule (#49)
#51Andrew Dunstan
andrew@dunslane.net
In reply to: Pavel Stehule (#49)
#52Pavel Stehule
pavel.stehule@gmail.com
In reply to: Andrew Dunstan (#51)
#53Simon Riggs
simon@2ndQuadrant.com
In reply to: Petr Jelinek (#50)
#54Andrew Dunstan
andrew@dunslane.net
In reply to: Simon Riggs (#53)
#55Mike Blackwell
mike.blackwell@rrd.com
In reply to: Andrew Dunstan (#54)
#56Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#54)
#57Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#56)
#58Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#57)
#59Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#58)
#60Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#56)
#61Pavel Stehule
pavel.stehule@gmail.com
In reply to: Robert Haas (#57)
#62Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#58)
#63Marko Tiikkaja
marko@joh.to
In reply to: Pavel Stehule (#62)
#64Tom Lane
tgl@sss.pgh.pa.us
In reply to: Marko Tiikkaja (#63)
#65Pavel Stehule
pavel.stehule@gmail.com
In reply to: Marko Tiikkaja (#63)
#66Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#64)
#67Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#66)
#68Simon Riggs
simon@2ndQuadrant.com
In reply to: Tom Lane (#67)
#69Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#64)
#70Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#69)
#71Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#70)
#72Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#71)
#73Pavel Stehule
pavel.stehule@gmail.com
In reply to: Robert Haas (#72)
#74Marko Tiikkaja
marko@joh.to
In reply to: Pavel Stehule (#73)
#75Pavel Stehule
pavel.stehule@gmail.com
In reply to: Marko Tiikkaja (#74)
#76Pavel Stehule
pavel.stehule@gmail.com
In reply to: Pavel Stehule (#75)
#77Pavel Stehule
pavel.stehule@gmail.com
In reply to: Pavel Stehule (#76)
#78Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Pavel Stehule (#77)
#79Pavel Stehule
pavel.stehule@gmail.com
In reply to: Alvaro Herrera (#78)
#80Pavel Stehule
pavel.stehule@gmail.com
In reply to: Pavel Stehule (#79)
#81Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Pavel Stehule (#80)
#82Pavel Stehule
pavel.stehule@gmail.com
In reply to: Jim Nasby (#81)
#83Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Pavel Stehule (#82)
#84Pavel Stehule
pavel.stehule@gmail.com
In reply to: Jim Nasby (#83)
#85Pavel Stehule
pavel.stehule@gmail.com
In reply to: Jim Nasby (#83)
#86Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Pavel Stehule (#85)
#87Pavel Stehule
pavel.stehule@gmail.com
In reply to: Jim Nasby (#86)
#88Pavel Stehule
pavel.stehule@gmail.com
In reply to: Jim Nasby (#86)
#89Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Pavel Stehule (#88)
#90Tom Lane
tgl@sss.pgh.pa.us
In reply to: Pavel Stehule (#88)
#91Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#90)
#92Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Pavel Stehule (#91)
#93Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jim Nasby (#92)
#94Pavel Stehule
pavel.stehule@gmail.com
In reply to: Tom Lane (#93)