<type>decimal</type>, <type>date</type>, <type>timestamp</type>,
and <type>interval</type> types. These data types cannot usefully be
mapped to primitive host variable types (such
as <type>int</type>, <type>long long int</type>,
or <type>char[]</type>), because they have a complex internal
structure. Applications deal with these types by declaring host
variables in special types and accessing them using functions in
the pgtypes library. The pgtypes library, described in detail
in <xref linkend="ecpg-pgtypes"/> contains basic functions to deal
with those types, such that you do not need to send a query to
the SQL server just for adding an interval to a time stamp for
example.
</para>
<para>
The follow subsections describe these special data types. For
more details about pgtypes library functions,
see <xref linkend="ecpg-pgtypes"/>.
</para>
<sect4 id="ecpg-special-types-timestamp-date">
<title>timestamp, date</title>
<para>
Here is a pattern for handling <type>timestamp</type> variables
in the ECPG host application.
</para>
<para>
First, the program has to include the header file for the
<type>timestamp</type> type:
<programlisting>
#include <pgtypes_timestamp.h>
</programlisting>
</para>
<para>
Next, declare a host variable as type <type>timestamp</type> in
the declare section:
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
timestamp ts;
EXEC SQL END DECLARE SECTION;
</programlisting>
</para>
<para>
And after reading a value into the host variable, process it
using pgtypes library functions. In following example, the
<type>timestamp</type> value is converted into text (ASCII) form
with the <function>PGTYPEStimestamp_to_asc()</function>
function:
<programlisting>
EXEC SQL SELECT now()::timestamp INTO :ts;
printf("ts = %s\n", PGTYPEStimestamp_to_asc(ts));
</programlisting>
This example will show some result like following:
<screen>
ts = 2010-06-27 18:03:56.949343
</screen>
</para>
<para>
In addition, the DATE type can be handled in the same way. The
program has to include <filename>pgtypes_date.h</filename>, declare a host variable
as the date type and convert a DATE value into a text form using
<function>PGTYPESdate_to_asc()</function> function. For more details about the
pgtypes library functions, see <xref linkend="ecpg-pgtypes"/>.
</para>
</sect4>
<sect4 id="ecpg-type-interval">
<title>interval</title>
<para>
The handling of the <type>interval</type> type is also similar
to the <type>timestamp</type> and <type>date</type> types. It
is required, however, to allocate memory for
an <type>interval</type> type value explicitly. In other words,
the memory space for the variable has to be allocated in the
heap memory, not in the stack memory.
</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