<!--
-$PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.45 2004/08/08 22:40:46 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.46 2004/08/16 17:52:06 tgl Exp $
-->
<chapter id="plpgsql">
</para>
</sect2>
+ <sect2 id="plpgsql-statements-null">
+ <title>Doing Nothing At All</title>
+
+ <para>
+ Sometimes a placeholder statement that does nothing is useful.
+ For example, it can indicate that one arm of an if/then/else
+ chain is deliberately empty. For this purpose, use the
+ <command>NULL</command> statement:
+
+<synopsis>
+NULL;
+</synopsis>
+ </para>
+
+ <para>
+ For example, the following two fragments of code are equivalent:
+<programlisting>
+ BEGIN
+ y := x / 0;
+ EXCEPTION
+ WHEN division_by_zero THEN
+ NULL; -- ignore the error
+ END;
+</programlisting>
+
+<programlisting>
+ BEGIN
+ y := x / 0;
+ EXCEPTION
+ WHEN division_by_zero THEN -- ignore the error
+ END;
+</programlisting>
+ Which is preferable is a matter of taste.
+ </para>
+
+ <note>
+ <para>
+ In Oracle's PL/SQL, empty statement lists are not allowed, and so
+ <command>NULL</> statements are <emphasis>required</> for situations
+ such as this. <application>PL/pgSQL</application> allows you to
+ just write nothing, instead.
+ </para>
+ </note>
+
+ </sect2>
+
<sect2 id="plpgsql-statements-executing-dyn">
<title>Executing Dynamic Commands</title>
<para>
When working with dynamic commands you will often have to handle escaping
of single quotes. The recommended method for quoting fixed text in your
- function body is dollar quoting. If you have legacy code which does
+ function body is dollar quoting. If you have legacy code that does
not use dollar quoting, please refer to the
overview in <xref linkend="plpgsql-quote-tips">, which can save you
some effort when translating said code to a more reasonable scheme.
</para>
<para>
- An example (this assumes that you are using dollar quoting, so the
- quote marks need not be doubled):
+ An example (this assumes that you are using dollar quoting for the
+ function as a whole, so the quote marks need not be doubled):
<programlisting>
EXECUTE 'UPDATE tbl SET '
|| quote_ident(colname)
|| ' = '
|| quote_literal(newvalue)
- || ' WHERE ...';
+ || ' WHERE key = '
+ || quote_literal(keyvalue);
</programlisting>
</para>
|| quote_ident(colname)
|| ' = $$'
|| newvalue
- || '$$ WHERE ...';
+ || '$$ WHERE key = '
+ || quote_literal(keyvalue);
</programlisting>
because it would break if the contents of <literal>newvalue</>
happened to contain <literal>$$</>. The same objection would
* procedural language
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.59 2004/07/31 23:04:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.60 2004/08/16 17:52:06 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
%type <stmt> stmt_return stmt_return_next stmt_raise stmt_execsql
%type <stmt> stmt_for stmt_select stmt_perform
%type <stmt> stmt_dynexecute stmt_getdiag
-%type <stmt> stmt_open stmt_fetch stmt_close
+%type <stmt> stmt_open stmt_fetch stmt_close stmt_null
%type <exceptions> exception_sect proc_exceptions
%type <exception> proc_exception
proc_stmts : proc_stmts proc_stmt
{
+ if ($2 != NULL)
+ {
if ($1->stmts_used == $1->stmts_alloc)
{
$1->stmts_alloc *= 2;
$1->stmts = realloc($1->stmts, sizeof(PLpgSQL_stmt *) * $1->stmts_alloc);
}
$1->stmts[$1->stmts_used++] = $2;
-
- $$ = $1;
+ }
+ $$ = $1;
}
| proc_stmt
{
- PLpgSQL_stmts *new;
+ PLpgSQL_stmts *new;
- new = malloc(sizeof(PLpgSQL_stmts));
- memset(new, 0, sizeof(PLpgSQL_stmts));
+ new = malloc(sizeof(PLpgSQL_stmts));
+ memset(new, 0, sizeof(PLpgSQL_stmts));
- new->stmts_alloc = 64;
- new->stmts_used = 1;
- new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc);
- new->stmts[0] = $1;
+ new->stmts_alloc = 32;
+ new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc);
- $$ = new;
+ if ($1 != NULL)
+ new->stmts[new->stmts_used++] = $1;
+ $$ = new;
}
;
{ $$ = $1; }
| stmt_close
{ $$ = $1; }
+ | stmt_null
+ { $$ = $1; }
;
stmt_perform : K_PERFORM lno expr_until_semi
}
;
+stmt_null : K_NULL ';'
+ {
+ /* We do not bother building a node for NULL */
+ $$ = NULL;
+ }
+ ;
+
cursor_varptr : T_SCALAR
{
if (yylval.scalar->dtype != PLPGSQL_DTYPE_VAR)