mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-28 00:21:50 +02:00
Add trivial NULL statement to plpgsql, for Oracle compatibility.
This commit is contained in:
parent
bc91389df9
commit
64410289f8
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$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">
|
||||
@ -1098,6 +1098,52 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query);
|
||||
</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>
|
||||
|
||||
@ -1129,7 +1175,7 @@ EXECUTE <replaceable class="command">command-string</replaceable>;
|
||||
<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.
|
||||
@ -1158,14 +1204,15 @@ EXECUTE <replaceable class="command">command-string</replaceable>;
|
||||
</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>
|
||||
|
||||
@ -1193,7 +1240,8 @@ EXECUTE 'UPDATE tbl SET '
|
||||
|| 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
|
||||
|
@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
*
|
||||
@ -132,7 +132,7 @@ static void check_assignable(PLpgSQL_datum *datum);
|
||||
%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
|
||||
@ -592,29 +592,31 @@ proc_sect :
|
||||
|
||||
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;
|
||||
}
|
||||
;
|
||||
|
||||
@ -654,6 +656,8 @@ proc_stmt : pl_block ';'
|
||||
{ $$ = $1; }
|
||||
| stmt_close
|
||||
{ $$ = $1; }
|
||||
| stmt_null
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
stmt_perform : K_PERFORM lno expr_until_semi
|
||||
@ -1493,6 +1497,13 @@ stmt_close : K_CLOSE lno cursor_variable ';'
|
||||
}
|
||||
;
|
||||
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user