</para>
<para>
Here is an example program:
<programlisting>
#include <stdio.h>
#include <stdlib.h>
#include <pgtypes_interval.h>
int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
interval *in;
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO testdb;
EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
in = PGTYPESinterval_new();
EXEC SQL SELECT '1 min'::interval INTO :in;
printf("interval = %s\n", PGTYPESinterval_to_asc(in));
PGTYPESinterval_free(in);
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
return 0;
}
</programlisting>
</para>
</sect4>
<sect4 id="ecpg-type-numeric-decimal">
<title>numeric, decimal</title>
<para>
The handling of the <type>numeric</type>
and <type>decimal</type> types is similar to the
<type>interval</type> type: It requires defining a pointer,
allocating some memory space on the heap, and accessing the
variable using the pgtypes library functions. For more details
about the pgtypes library functions,
see <xref linkend="ecpg-pgtypes"/>.
</para>
<para>
No functions are provided specifically for
the <type>decimal</type> type. An application has to convert it
to a <type>numeric</type> variable using a pgtypes library
function to do further processing.
</para>
<para>
Here is an example program handling <type>numeric</type>
and <type>decimal</type> type variables.
<programlisting>
#include <stdio.h>
#include <stdlib.h>
#include <pgtypes_numeric.h>
EXEC SQL WHENEVER SQLERROR STOP;
int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
numeric *num;
numeric *num2;
decimal *dec;
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO testdb;
EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
num = PGTYPESnumeric_new();
dec = PGTYPESdecimal_new();
EXEC SQL SELECT 12.345::numeric(4,2), 23.456::decimal(4,2) INTO :num, :dec;
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 0));
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 1));
printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 2));
/* Convert decimal to numeric to show a decimal value. */
num2 = PGTYPESnumeric_new();
PGTYPESnumeric_from_decimal(dec, num2);
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 0));
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 1));
printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 2));
PGTYPESnumeric_free(num2);
PGTYPESdecimal_free(dec);
PGTYPESnumeric_free(num);
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
return 0;
}
</programlisting>
</para>
</sect4>
<sect4 id="ecpg-special-types-bytea">
<title>bytea</title>
<para>
The handling of the <type>bytea</type> type is similar to
that of <type>VARCHAR</type>. The definition on an array of type
<type>bytea</type> is converted into a named struct for every
variable. A declaration like:
<programlisting>
bytea var[180];
</programlisting>
is converted into:
<programlisting>
struct bytea_var { int len; char arr[180]; } var;
</programlisting>
The member <structfield>arr</structfield> hosts binary format
data. It can also handle <literal>'\0'</literal> as part of
data, unlike <type>VARCHAR</type>.
The data is converted from/to hex format and sent/received by
ecpglib.
</para>
<note>
<para>
<type>bytea</type> variable can be used only when
<xref linkend="guc-bytea-output"/> is set to <literal>hex</literal>.
</para>
</note>
</sect4>
</sect3>
<sect3 id="ecpg-variables-nonprimitive-c">
<title>Host Variables with Nonprimitive Types</title>
<para>
As a host variable you can also use arrays, typedefs, structs, and
pointers.
</para>
<sect4 id="ecpg-variables-arrays">
<title>Arrays</title>