Home Explore Blog CI



postgresql

66th chunk of `doc/src/sgml/plpgsql.sgml`
3bb78b72cfc37ac069e53301f4f004ef20fb9352fdb0bfba0000000100000fa5
 <literal>key</literal> even if it happens
     to have different types in different tables.
    </para>

    <para>
     Likewise, functions having polymorphic argument types have a separate
     statement cache for each combination of actual argument types they have
     been invoked for, so that data type differences do not cause unexpected
     failures.
    </para>

   <para>
    Statement caching can sometimes have surprising effects on the
    interpretation of time-sensitive values.  For example there
    is a difference between what these two functions do:

<programlisting>
CREATE FUNCTION logfunc1(logtxt text) RETURNS void AS $$
    BEGIN
        INSERT INTO logtable VALUES (logtxt, 'now');
    END;
$$ LANGUAGE plpgsql;
</programlisting>

     and:

<programlisting>
CREATE FUNCTION logfunc2(logtxt text) RETURNS void AS $$
    DECLARE
        curtime timestamp;
    BEGIN
        curtime := 'now';
        INSERT INTO logtable VALUES (logtxt, curtime);
    END;
$$ LANGUAGE plpgsql;
</programlisting>
    </para>

    <para>
     In the case of <function>logfunc1</function>, the
     <productname>PostgreSQL</productname> main parser knows when
     analyzing the <command>INSERT</command> that the
     string <literal>'now'</literal> should be interpreted as
     <type>timestamp</type>, because the target column of
     <classname>logtable</classname> is of that type. Thus,
     <literal>'now'</literal> will be converted to a <type>timestamp</type>
     constant when the
     <command>INSERT</command> is analyzed, and then used in all
     invocations of <function>logfunc1</function> during the lifetime
     of the session. Needless to say, this isn't what the programmer
     wanted.  A better idea is to use the <literal>now()</literal> or
     <literal>current_timestamp</literal> function.
    </para>

    <para>
     In the case of <function>logfunc2</function>, the
     <productname>PostgreSQL</productname> main parser does not know
     what type <literal>'now'</literal> should become and therefore
     it returns a data value of type <type>text</type> containing the string
     <literal>now</literal>. During the ensuing assignment
     to the local variable <varname>curtime</varname>, the
     <application>PL/pgSQL</application> interpreter casts this
     string to the <type>timestamp</type> type by calling the
     <function>textout</function> and <function>timestamp_in</function>
     functions for the conversion.  So, the computed time stamp is updated
     on each execution as the programmer expects.  Even though this
     happens to work as expected, it's not terribly efficient, so
     use of the <literal>now()</literal> function would still be a better idea.
    </para>

  </sect2>

  </sect1>

 <sect1 id="plpgsql-development-tips">
  <title>Tips for Developing in <application>PL/pgSQL</application></title>

   <para>
    One good way to develop in
    <application>PL/pgSQL</application> is to use the text editor of your
    choice to create your functions, and in another window, use
    <application>psql</application> to load and test those functions.
    If you are doing it this way, it
    is a good idea to write the function using <command>CREATE OR
    REPLACE FUNCTION</command>. That way you can just reload the file to update
    the function definition.  For example:
<programlisting>
CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $$
          ....
$$ LANGUAGE plpgsql;
</programlisting>
   </para>

   <para>
    While running <application>psql</application>, you can load or reload such
    a function definition file with:
<programlisting>
\i filename.sql
</programlisting>
    and then immediately issue SQL commands to test the function.
   </para>

   <para>
    Another good way to develop in <application>PL/pgSQL</application> is with a
    GUI database access tool that facilitates development in a
    procedural language. One example of such a tool is
    <application>pgAdmin</application>,

Title: PL/pgSQL Statement Caching and Development Tips
Summary
Statement caching in PL/pgSQL can lead to unexpected behavior with time-sensitive values, as demonstrated by two functions logging timestamps. The first function converts 'now' to a timestamp constant during parsing, remaining static across invocations. The second casts 'now' to text and then to timestamp during each execution, updating the timestamp. Using now() or current_timestamp is recommended for accurate time updates. For development, using CREATE OR REPLACE FUNCTION allows easy function updates. psql can load and test functions from files, and GUI tools like pgAdmin facilitate procedural language development.