handle. Note, however, that type casts, especially implicit
ones, should be introduced into the type system very carefully.
</para>
<para>
For example,
<programlisting>
CREATE FUNCTION create_complex(r double, i double) RETURNS complex
LANGUAGE SQL
IMMUTABLE
AS $$ SELECT $1 * complex '(1,0')' + $2 * complex '(0,1)' $$;
</programlisting>
After this definition, the following
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
double a, b, c, d;
EXEC SQL END DECLARE SECTION;
a = 1;
b = 2;
c = 3;
d = 4;
EXEC SQL INSERT INTO test_complex VALUES (create_complex(:a, :b), create_complex(:c, :d));
</programlisting>
has the same effect as
<programlisting>
EXEC SQL INSERT INTO test_complex VALUES ('(1,2)', '(3,4)');
</programlisting>
</para>
</sect3>
</sect2>
<sect2 id="ecpg-indicators">
<title>Indicators</title>
<para>
The examples above do not handle null values. In fact, the
retrieval examples will raise an error if they fetch a null value
from the database. To be able to pass null values to the database
or retrieve null values from the database, you need to append a
second host variable specification to each host variable that
contains data. This second host variable is called the
<firstterm>indicator</firstterm> and contains a flag that tells
whether the datum is null, in which case the value of the real
host variable is ignored. Here is an example that handles the
retrieval of null values correctly:
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR val;
int val_ind;
EXEC SQL END DECLARE SECTION:
...
EXEC SQL SELECT b INTO :val :val_ind FROM test1;
</programlisting>
The indicator variable <varname>val_ind</varname> will be zero if
the value was not null, and it will be negative if the value was
null. (See <xref linkend="ecpg-oracle-compat"/> to enable
Oracle-specific behavior.)
</para>
<para>
The indicator has another function: if the indicator value is
positive, it means that the value is not null, but it was
truncated when it was stored in the host variable.
</para>
<para>
If the argument <literal>-r no_indicator</literal> is passed to
the preprocessor <command>ecpg</command>, it works in
<quote>no-indicator</quote> mode. In no-indicator mode, if no
indicator variable is specified, null values are signaled (on
input and output) for character string types as empty string and
for integer types as the lowest possible value for type (for
example, <symbol>INT_MIN</symbol> for <type>int</type>).
</para>
</sect2>
</sect1>
<sect1 id="ecpg-dynamic">
<title>Dynamic SQL</title>
<para>
In many cases, the particular SQL statements that an application
has to execute are known at the time the application is written.
In some cases, however, the SQL statements are composed at run time
or provided by an external source. In these cases you cannot embed
the SQL statements directly into the C source code, but there is a
facility that allows you to call arbitrary SQL statements that you
provide in a string variable.
</para>
<sect2 id="ecpg-dynamic-without-result">
<title>Executing Statements without a Result Set</title>
<para>
The simplest way to execute an arbitrary SQL statement is to use
the command <command>EXECUTE IMMEDIATE</command>. For example:
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "CREATE TABLE test1 (...);";
EXEC SQL END DECLARE SECTION;
EXEC SQL EXECUTE IMMEDIATE :stmt;
</programlisting>
<command>EXECUTE IMMEDIATE</command> can be used for SQL
statements that do not return a result set (e.g.,
DDL, <command>INSERT</command>, <command>UPDATE</command>,
<command>DELETE</command>). You cannot execute statements that
retrieve data (e.g., <command>SELECT</command>) this way. The
next section describes how to do that.
</para>
</sect2>
<sect2 id="ecpg-dynamic-input">