<application>PL/pgSQL</application>
statements are processed using the server's main
<acronym>SQL</acronym> executor. For example, when you write
a <application>PL/pgSQL</application> statement like
<synopsis>
IF <replaceable>expression</replaceable> THEN ...
</synopsis>
<application>PL/pgSQL</application> will evaluate the expression by
feeding a query like
<synopsis>
SELECT <replaceable>expression</replaceable>
</synopsis>
to the main SQL engine. While forming the <command>SELECT</command> command,
any occurrences of <application>PL/pgSQL</application> variable names
are replaced by query parameters, as discussed in detail in
<xref linkend="plpgsql-var-subst"/>.
This allows the query plan for the <command>SELECT</command> to
be prepared just once and then reused for subsequent
evaluations with different values of the variables. Thus, what
really happens on first use of an expression is essentially a
<command>PREPARE</command> command. For example, if we have declared
two integer variables <literal>x</literal> and <literal>y</literal>, and we write
<programlisting>
IF x < y THEN ...
</programlisting>
what happens behind the scenes is equivalent to
<programlisting>
PREPARE <replaceable>statement_name</replaceable>(integer, integer) AS SELECT $1 < $2;
</programlisting>
and then this prepared statement is <command>EXECUTE</command>d for each
execution of the <command>IF</command> statement, with the current values
of the <application>PL/pgSQL</application> variables supplied as
parameter values. Normally these details are
not important to a <application>PL/pgSQL</application> user, but
they are useful to know when trying to diagnose a problem.
More information appears in <xref linkend="plpgsql-plan-caching"/>.
</para>
<para>
Since an <replaceable>expression</replaceable> is converted to a
<literal>SELECT</literal> command, it can contain the same clauses
that an ordinary <literal>SELECT</literal> would, except that it
cannot include a top-level <literal>UNION</literal>,
<literal>INTERSECT</literal>, or <literal>EXCEPT</literal> clause.
Thus for example one could test whether a table is non-empty with
<programlisting>
IF count(*) > 0 FROM my_table THEN ...
</programlisting>
since the <replaceable>expression</replaceable>
between <literal>IF</literal> and <literal>THEN</literal> is parsed as
though it were <literal>SELECT count(*) > 0 FROM my_table</literal>.
The <literal>SELECT</literal> must produce a single column, and not
more than one row. (If it produces no rows, the result is taken as
NULL.)
</para>
</sect1>
<sect1 id="plpgsql-statements">
<title>Basic Statements</title>
<para>
In this section and the following ones, we describe all the statement
types that are explicitly understood by
<application>PL/pgSQL</application>.
Anything not recognized as one of these statement types is presumed
to be an SQL command and is sent to the main database engine to execute,
as described in <xref linkend="plpgsql-statements-general-sql"/>.
</para>
<sect2 id="plpgsql-statements-assignment">
<title>Assignment</title>
<para>
An assignment of a value to a <application>PL/pgSQL</application>
variable is written as:
<synopsis>
<replaceable>variable</replaceable> { := | = } <replaceable>expression</replaceable>;
</synopsis>
As explained previously, the expression in such a statement is evaluated
by means of an SQL <command>SELECT</command> command sent to the main
database engine. The expression must yield a single value (possibly
a row value, if the variable is a row or record variable). The target
variable can be a simple variable (optionally qualified with a block
name), a field of a row or record target, or an element or slice of
an array target.