<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>,