]> granicus.if.org Git - postgresql/commitdiff
Add trivial NULL statement to plpgsql, for Oracle compatibility.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 16 Aug 2004 17:52:06 +0000 (17:52 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 16 Aug 2004 17:52:06 +0000 (17:52 +0000)
doc/src/sgml/plpgsql.sgml
src/pl/plpgsql/src/gram.y

index 5e21d1abb68e8ad18c58398d883372b4add1889d..ff2b4b2a74958f285d106c481b2d2a29fcd60472 100644 (file)
@@ -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
index 96c5c61725dcdad56537f577d5c68f6b7dd3270f..c5c6ddf703ccfcc8c298284d7e87a2b6d5a2b23f 100644 (file)
@@ -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)