Multi-dimensional SQL-level arrays are not directly supported in ECPG.
One-dimensional SQL-level arrays can be mapped into C array host
variables and vice-versa. However, when creating a statement ecpg does
not know the types of the columns, so that it cannot check if a C array
is input into a corresponding SQL-level array. When processing the
output of an SQL statement, ecpg has the necessary information and thus
checks if both are arrays.
</para>
<para>
If a query accesses <emphasis>elements</emphasis> of an array
separately, then this avoids the use of arrays in ECPG. Then, a
host variable with a type that can be mapped to the element type
should be used. For example, if a column type is array of
<type>integer</type>, a host variable of type <type>int</type>
can be used. Also if the element type is <type>varchar</type>
or <type>text</type>, a host variable of type <type>char[]</type>
or <type>VARCHAR[]</type> can be used.
</para>
<para>
Here is an example. Assume the following table:
<programlisting>
CREATE TABLE t3 (
ii integer[]
);
testdb=> SELECT * FROM t3;
ii
-------------
{1,2,3,4,5}
(1 row)
</programlisting>
The following example program retrieves the 4th element of the
array and stores it into a host variable of
type <type>int</type>:
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
int ii;
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii[4] FROM t3;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH FROM cur1 INTO :ii ;
printf("ii=%d\n", ii);
}
EXEC SQL CLOSE cur1;
</programlisting>
This example shows the following result:
<screen>
ii=4
</screen>
</para>
<para>
To map multiple array elements to the multiple elements in an
array type host variables each element of array column and each
element of the host variable array have to be managed separately,
for example:
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
int ii_a[8];
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii[1], ii[2], ii[3], ii[4] FROM t3;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH FROM cur1 INTO :ii_a[0], :ii_a[1], :ii_a[2], :ii_a[3];
...
}
</programlisting>
</para>
<para>
Note again that
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
int ii_a[8];
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii FROM t3;
EXEC SQL OPEN cur1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
/* WRONG */
EXEC SQL FETCH FROM cur1 INTO :ii_a;
...
}
</programlisting>
would not work correctly in this case, because you cannot map an
array type column to an array host variable directly.
</para>
<para>
Another workaround is to store arrays in their external string
representation in host variables of type <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