The identifier serves as the <quote>variable name</quote> of the
descriptor area. <!-- The scope of the allocated descriptor is WHAT?. -->
When you don't need the descriptor anymore, you should deallocate
it:
<programlisting>
EXEC SQL DEALLOCATE DESCRIPTOR <replaceable>identifier</replaceable>;
</programlisting>
</para>
<para>
To use a descriptor area, specify it as the storage target in an
<literal>INTO</literal> clause, instead of listing host variables:
<programlisting>
EXEC SQL FETCH NEXT FROM mycursor INTO SQL DESCRIPTOR mydesc;
</programlisting>
If the result set is empty, the Descriptor Area will still contain
the metadata from the query, i.e., the field names.
</para>
<para>
For not yet executed prepared queries, the <command>DESCRIBE</command>
statement can be used to get the metadata of the result set:
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
char *sql_stmt = "SELECT * FROM table1";
EXEC SQL END DECLARE SECTION;
EXEC SQL PREPARE stmt1 FROM :sql_stmt;
EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc;
</programlisting>
</para>
<para>
Before PostgreSQL 9.0, the <literal>SQL</literal> keyword was optional,
so using <literal>DESCRIPTOR</literal> and <literal>SQL DESCRIPTOR</literal>
produced named SQL Descriptor Areas. Now it is mandatory, omitting
the <literal>SQL</literal> keyword produces SQLDA Descriptor Areas,
see <xref linkend="ecpg-sqlda-descriptors"/>.
</para>
<para>
In <command>DESCRIBE</command> and <command>FETCH</command> statements,
the <literal>INTO</literal> and <literal>USING</literal> keywords can be
used to similarly: they produce the result set and the metadata in a
Descriptor Area.
</para>
<para>
Now how do you get the data out of the descriptor area? You can
think of the descriptor area as a structure with named fields. To
retrieve the value of a field from the header and store it into a
host variable, use the following command:
<programlisting>
EXEC SQL GET DESCRIPTOR <replaceable>name</replaceable> :<replaceable>hostvar</replaceable> = <replaceable>field</replaceable>;
</programlisting>
Currently, there is only one header field defined:
<replaceable>COUNT</replaceable>, which tells how many item
descriptor areas exist (that is, how many columns are contained in
the result). The host variable needs to be of an integer type. To
get a field from the item descriptor area, use the following
command:
<programlisting>
EXEC SQL GET DESCRIPTOR <replaceable>name</replaceable> VALUE <replaceable>num</replaceable> :<replaceable>hostvar</replaceable> = <replaceable>field</replaceable>;
</programlisting>
<replaceable>num</replaceable> can be a literal integer or a host
variable containing an integer. Possible fields are:
<variablelist>
<varlistentry id="ecpg-named-descriptors-cardinality">
<term><literal>CARDINALITY</literal> (integer)</term>
<listitem>
<para>
number of rows in the result set
</para>
</listitem>
</varlistentry>
<varlistentry id="ecpg-named-descriptors-data">
<term><literal>DATA</literal></term>
<listitem>
<para>
actual data item (therefore, the data type of this field
depends on the query)
</para>
</listitem>
</varlistentry>
<varlistentry id="ecpg-named-descriptors-datetime-interval-code">
<term><literal>DATETIME_INTERVAL_CODE</literal> (integer)</term>
<listitem>
<para>
When <literal>TYPE</literal> is <literal>9</literal>,
<literal>DATETIME_INTERVAL_CODE</literal> will have a value of
<literal>1</literal> for <literal>DATE</literal>,
<literal>2</literal> for <literal>TIME</literal>,
<literal>3</literal> for <literal>TIMESTAMP</literal>,
<literal>4</literal> for <literal>TIME WITH TIME ZONE</literal>, or
<literal>5</literal> for <literal>TIMESTAMP