<type>char[]</type>
or <type>VARCHAR[]</type>. For more details about this
representation, see <xref linkend="arrays-input"/>. Note that
this means that the array cannot be accessed naturally as an
array in the host program (without further processing that parses
the text representation).
</para>
</sect3>
<sect3 id="ecpg-variables-nonprimitive-sql-composite">
<title>Composite Types</title>
<para>
Composite types are not directly supported in ECPG, but an easy workaround is possible.
The
available workarounds are similar to the ones described for
arrays above: Either access each attribute separately or use the
external string representation.
</para>
<para>
For the following examples, assume the following type and table:
<programlisting>
CREATE TYPE comp_t AS (intval integer, textval varchar(32));
CREATE TABLE t4 (compval comp_t);
INSERT INTO t4 VALUES ( (256, 'PostgreSQL') );
</programlisting>
The most obvious solution is to access each attribute separately.
The following program retrieves data from the example table by
selecting each attribute of the type <type>comp_t</type>
separately:
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
int intval;
varchar textval[33];
EXEC SQL END DECLARE SECTION;
/* Put each element of the composite type column in the SELECT list. */
EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).intval, (compval).textval FROM t4;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
/* Fetch each element of the composite type column into host variables. */
EXEC SQL FETCH FROM cur1 INTO :intval, :textval;
printf("intval=%d, textval=%s\n", intval, textval.arr);
}
EXEC SQL CLOSE cur1;
</programlisting>
</para>
<para>
To enhance this example, the host variables to store values in
the <command>FETCH</command> command can be gathered into one
structure. For more details about the host variable in the
structure form, see <xref linkend="ecpg-variables-struct"/>.
To switch to the structure, the example can be modified as below.
The two host variables, <varname>intval</varname>
and <varname>textval</varname>, become members of
the <structname>comp_t</structname> structure, and the structure
is specified on the <command>FETCH</command> command.
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
typedef struct
{
int intval;
varchar textval[33];
} comp_t;
comp_t compval;
EXEC SQL END DECLARE SECTION;
/* Put each element of the composite type column in the SELECT list. */
EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).intval, (compval).textval FROM t4;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
/* Put all values in the SELECT list into one structure. */
EXEC SQL FETCH FROM cur1 INTO :compval;
printf("intval=%d, textval=%s\n", compval.intval, compval.textval.arr);
}
EXEC SQL CLOSE cur1;
</programlisting>
Although a structure is used in the <command>FETCH</command>
command, the attribute names in the <command>SELECT</command>
clause are specified one by one. This can be enhanced by using
a <literal>*</literal> to ask for all attributes of the composite
type value.
<programlisting>
...
EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).* FROM t4;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
/* Put all values in the SELECT list into one structure. */
EXEC SQL FETCH FROM cur1 INTO :compval;
printf("intval=%d, textval=%s\n", compval.intval, compval.textval.arr);
}
...
</programlisting>
This way, composite types can be mapped into structures almost
seamlessly, even though ECPG does not understand the composite
type itself.
</para>
<para>
Finally, it is also possible to store composite type values in
their external string representation in host variables of
type <type>char[]</type> or