Commit aa7f0046 authored by Alvaro Herrera's avatar Alvaro Herrera

Desultorily enclose programlisting tags in CDATA, to get rid of some obnoxious

SGML-escaping.
parent b2971e20
<!-- $PostgreSQL: pgsql/doc/src/sgml/auto-explain.sgml,v 1.1 2008/11/19 02:59:28 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/auto-explain.sgml,v 1.2 2008/12/07 23:46:39 alvherre Exp $ -->
<sect1 id="auto-explain"> <sect1 id="auto-explain">
<title>auto_explain</title> <title>auto_explain</title>
...@@ -150,18 +150,19 @@ explain.log_min_duration = '3s' ...@@ -150,18 +150,19 @@ explain.log_min_duration = '3s'
This might produce log output such as: This might produce log output such as:
</para> </para>
<programlisting> <programlisting><![CDATA[
LOG: duration: 0.986 ms plan: LOG: duration: 0.986 ms plan:
Aggregate (cost=14.90..14.91 rows=1 width=0) Aggregate (cost=14.90..14.91 rows=1 width=0)
-&gt; Hash Join (cost=3.91..14.70 rows=81 width=0) -> Hash Join (cost=3.91..14.70 rows=81 width=0)
Hash Cond: (pg_class.oid = pg_index.indrelid) Hash Cond: (pg_class.oid = pg_index.indrelid)
-&gt; Seq Scan on pg_class (cost=0.00..8.27 rows=227 width=4) -> Seq Scan on pg_class (cost=0.00..8.27 rows=227 width=4)
-&gt; Hash (cost=2.90..2.90 rows=81 width=4) -> Hash (cost=2.90..2.90 rows=81 width=4)
-&gt; Seq Scan on pg_index (cost=0.00..2.90 rows=81 width=4) -> Seq Scan on pg_index (cost=0.00..2.90 rows=81 width=4)
Filter: indisunique Filter: indisunique
STATEMENT: SELECT count(*) STATEMENT: SELECT count(*)
FROM pg_class, pg_index FROM pg_class, pg_index
WHERE oid = indrelid AND indisunique; WHERE oid = indrelid AND indisunique;
]]>
</programlisting> </programlisting>
</sect2> </sect2>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/ecpg.sgml,v 1.86 2008/06/12 19:15:40 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/ecpg.sgml,v 1.87 2008/12/07 23:46:39 alvherre Exp $ -->
<chapter id="ecpg"> <chapter id="ecpg">
<title><application>ECPG</application> - Embedded <acronym>SQL</acronym> in C</title> <title><application>ECPG</application> - Embedded <acronym>SQL</acronym> in C</title>
...@@ -717,9 +717,9 @@ EXEC SQL EXECUTE mystmt USING 42, 'foobar'; ...@@ -717,9 +717,9 @@ EXEC SQL EXECUTE mystmt USING 42, 'foobar';
</programlisting> </programlisting>
If the statement you are executing returns values, then add an If the statement you are executing returns values, then add an
<literal>INTO</literal> clause: <literal>INTO</literal> clause:
<programlisting> <programlisting><![CDATA[
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
const char *stmt = "SELECT a, b, c FROM test1 WHERE a &gt; ?"; const char *stmt = "SELECT a, b, c FROM test1 WHERE a > ?";
int v1, v2; int v1, v2;
VARCHAR v3; VARCHAR v3;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
...@@ -727,6 +727,7 @@ EXEC SQL END DECLARE SECTION; ...@@ -727,6 +727,7 @@ EXEC SQL END DECLARE SECTION;
EXEC SQL PREPARE mystmt FROM :stmt; EXEC SQL PREPARE mystmt FROM :stmt;
... ...
EXEC SQL EXECUTE mystmt INTO v1, v2, v3 USING 37; EXEC SQL EXECUTE mystmt INTO v1, v2, v3 USING 37;
]]>
</programlisting> </programlisting>
An <command>EXECUTE</command> command can have an An <command>EXECUTE</command> command can have an
<literal>INTO</literal> clause, a <literal>USING</literal> clause, <literal>INTO</literal> clause, a <literal>USING</literal> clause,
...@@ -752,7 +753,7 @@ EXEC SQL DEALLOCATE PREPARE <replaceable>name</replaceable>; ...@@ -752,7 +753,7 @@ EXEC SQL DEALLOCATE PREPARE <replaceable>name</replaceable>;
functions to do basic calculations with those types within C, i.e. without functions to do basic calculations with those types within C, i.e. without
the help of the <productname>PostgreSQL</productname> server. See the the help of the <productname>PostgreSQL</productname> server. See the
following example: following example:
<programlisting> <programlisting><![CDATA[
EXEC SQL BEGIN DECLARE SECTION; EXEC SQL BEGIN DECLARE SECTION;
date date1; date date1;
timestamp ts1, tsout; timestamp ts1, tsout;
...@@ -760,12 +761,13 @@ EXEC SQL BEGIN DECLARE SECTION; ...@@ -760,12 +761,13 @@ EXEC SQL BEGIN DECLARE SECTION;
char *out; char *out;
EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION;
PGTYPESdate_today(&amp;date1); PGTYPESdate_today(&date1);
EXEC SQL SELECT started, duration INTO :ts1, :iv1 FROM datetbl WHERE d=:date1; EXEC SQL SELECT started, duration INTO :ts1, :iv1 FROM datetbl WHERE d=:date1;
PGTYPEStimestamp_add_interval(&amp;ts1, &amp;iv1, &amp;tsout); PGTYPEStimestamp_add_interval(&ts1, &iv1, &tsout);
out = PGTYPEStimestamp_to_asc(&amp;tsout); out = PGTYPEStimestamp_to_asc(&tsout);
printf("Started + duration: %s\n", out); printf("Started + duration: %s\n", out);
free(out); free(out);
]]>
</programlisting> </programlisting>
</para> </para>
...@@ -3449,14 +3451,15 @@ int rsetnull(int t, char *ptr); ...@@ -3449,14 +3451,15 @@ int rsetnull(int t, char *ptr);
<para> <para>
Here is an example of a call to this function: Here is an example of a call to this function:
<programlisting> <programlisting><![CDATA[
$char c[] = "abc "; $char c[] = "abc ";
$short s = 17; $short s = 17;
$int i = -74874; $int i = -74874;
rsetnull(CCHARTYPE, (char *) c); rsetnull(CCHARTYPE, (char *) c);
rsetnull(CSHORTTYPE, (char *) &amp;s); rsetnull(CSHORTTYPE, (char *) &s);
rsetnull(CINTTYPE, (char *) &amp;i); rsetnull(CINTTYPE, (char *) &i);
]]>
</programlisting> </programlisting>
</para> </para>
</listitem> </listitem>
...@@ -3477,14 +3480,15 @@ int risnull(int t, char *ptr); ...@@ -3477,14 +3480,15 @@ int risnull(int t, char *ptr);
</para> </para>
<para> <para>
Here is an example of how to use this function: Here is an example of how to use this function:
<programlisting> <programlisting><![CDATA[
$char c[] = "abc "; $char c[] = "abc ";
$short s = 17; $short s = 17;
$int i = -74874; $int i = -74874;
risnull(CCHARTYPE, (char *) c); risnull(CCHARTYPE, (char *) c);
risnull(CSHORTTYPE, (char *) &amp;s); risnull(CSHORTTYPE, (char *) &s);
risnull(CINTTYPE, (char *) &amp;i); risnull(CINTTYPE, (char *) &i);
]]>
</programlisting> </programlisting>
</para> </para>
</listitem> </listitem>
...@@ -4960,11 +4964,11 @@ EXEC SQL END DECLARE SECTION; ...@@ -4960,11 +4964,11 @@ EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT res INTO :result FROM mytable WHERE index = :index; EXEC SQL SELECT res INTO :result FROM mytable WHERE index = :index;
</programlisting> </programlisting>
is translated into: is translated into:
<programlisting> <programlisting><![CDATA[
/* Processed by ecpg (2.6.0) */ /* Processed by ecpg (2.6.0) */
/* These two include files are added by the preprocessor */ /* These two include files are added by the preprocessor */
#include &lt;ecpgtype.h&gt;; #include <ecpgtype.h>;
#include &lt;ecpglib.h&gt;; #include <ecpglib.h>;
/* exec sql begin declare section */ /* exec sql begin declare section */
...@@ -4975,11 +4979,12 @@ EXEC SQL SELECT res INTO :result FROM mytable WHERE index = :index; ...@@ -4975,11 +4979,12 @@ EXEC SQL SELECT res INTO :result FROM mytable WHERE index = :index;
/* exec sql end declare section */ /* exec sql end declare section */
... ...
ECPGdo(__LINE__, NULL, "SELECT res FROM mytable WHERE index = ? ", ECPGdo(__LINE__, NULL, "SELECT res FROM mytable WHERE index = ? ",
ECPGt_int,&amp;(index),1L,1L,sizeof(int), ECPGt_int,&(index),1L,1L,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
ECPGt_int,&amp;(result),1L,1L,sizeof(int), ECPGt_int,&(result),1L,1L,sizeof(int),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
#line 147 "foo.pgc" #line 147 "foo.pgc"
]]>
</programlisting> </programlisting>
(The indentation here is added for readability and not (The indentation here is added for readability and not
something the preprocessor does.) something the preprocessor does.)
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.272 2008/12/02 12:42:11 mha Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.273 2008/12/07 23:46:39 alvherre Exp $ -->
<chapter id="libpq"> <chapter id="libpq">
<title><application>libpq</application> - C Library</title> <title><application>libpq</application> - C Library</title>
...@@ -5415,8 +5415,9 @@ int eventproc(PGEventId evtId, void *evtInfo, void *passThrough) ...@@ -5415,8 +5415,9 @@ int eventproc(PGEventId evtId, void *evtInfo, void *passThrough)
</para> </para>
<programlisting> <programlisting>
<![CDATA[
/* required header for libpq events (note: includes libpq-fe.h) */ /* required header for libpq events (note: includes libpq-fe.h) */
#include &lt;libpq-events.h&gt; #include <libpq-events.h>
/* The instanceData */ /* The instanceData */
typedef struct typedef struct
...@@ -5488,17 +5489,17 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) ...@@ -5488,17 +5489,17 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
case PGEVT_REGISTER: case PGEVT_REGISTER:
{ {
PGEventRegister *e = (PGEventRegister *)evtInfo; PGEventRegister *e = (PGEventRegister *)evtInfo;
mydata *data = get_mydata(e-&gt;conn); mydata *data = get_mydata(e->conn);
/* associate app specific data with connection */ /* associate app specific data with connection */
PQsetInstanceData(e-&gt;conn, myEventProc, data); PQsetInstanceData(e->conn, myEventProc, data);
break; break;
} }
case PGEVT_CONNRESET: case PGEVT_CONNRESET:
{ {
PGEventConnReset *e = (PGEventConnReset *)evtInfo; PGEventConnReset *e = (PGEventConnReset *)evtInfo;
mydata *data = PQinstanceData(e-&gt;conn, myEventProc); mydata *data = PQinstanceData(e->conn, myEventProc);
if (data) if (data)
memset(data, 0, sizeof(mydata)); memset(data, 0, sizeof(mydata));
...@@ -5508,7 +5509,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) ...@@ -5508,7 +5509,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
case PGEVT_CONNDESTROY: case PGEVT_CONNDESTROY:
{ {
PGEventConnDestroy *e = (PGEventConnDestroy *)evtInfo; PGEventConnDestroy *e = (PGEventConnDestroy *)evtInfo;
mydata *data = PQinstanceData(e-&gt;conn, myEventProc); mydata *data = PQinstanceData(e->conn, myEventProc);
/* free instance data because the conn is being destroyed */ /* free instance data because the conn is being destroyed */
if (data) if (data)
...@@ -5519,29 +5520,29 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) ...@@ -5519,29 +5520,29 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
case PGEVT_RESULTCREATE: case PGEVT_RESULTCREATE:
{ {
PGEventResultCreate *e = (PGEventResultCreate *)evtInfo; PGEventResultCreate *e = (PGEventResultCreate *)evtInfo;
mydata *conn_data = PQinstanceData(e-&gt;conn, myEventProc); mydata *conn_data = PQinstanceData(e->conn, myEventProc);
mydata *res_data = dup_mydata(conn_data); mydata *res_data = dup_mydata(conn_data);
/* associate app specific data with result (copy it from conn) */ /* associate app specific data with result (copy it from conn) */
PQsetResultInstanceData(e-&gt;result, myEventProc, res_data); PQsetResultInstanceData(e->result, myEventProc, res_data);
break; break;
} }
case PGEVT_RESULTCOPY: case PGEVT_RESULTCOPY:
{ {
PGEventResultCopy *e = (PGEventResultCopy *)evtInfo; PGEventResultCopy *e = (PGEventResultCopy *)evtInfo;
mydata *src_data = PQresultInstanceData(e-&gt;src, myEventProc); mydata *src_data = PQresultInstanceData(e->src, myEventProc);
mydata *dest_data = dup_mydata(src_data); mydata *dest_data = dup_mydata(src_data);
/* associate app specific data with result (copy it from a result) */ /* associate app specific data with result (copy it from a result) */
PQsetResultInstanceData(e-&gt;dest, myEventProc, dest_data); PQsetResultInstanceData(e->dest, myEventProc, dest_data);
break; break;
} }
case PGEVT_RESULTDESTROY: case PGEVT_RESULTDESTROY:
{ {
PGEventResultDestroy *e = (PGEventResultDestroy *)evtInfo; PGEventResultDestroy *e = (PGEventResultDestroy *)evtInfo;
mydata *data = PQresultInstanceData(e-&gt;result, myEventProc); mydata *data = PQresultInstanceData(e->result, myEventProc);
/* free instance data because the result is being destroyed */ /* free instance data because the result is being destroyed */
if (data) if (data)
...@@ -5556,6 +5557,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) ...@@ -5556,6 +5557,7 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
return TRUE; /* event processing succeeded */ return TRUE; /* event processing succeeded */
} }
]]>
</programlisting> </programlisting>
</sect2> </sect2>
</sect1> </sect1>
...@@ -6407,13 +6409,14 @@ testlibpq.o(.text+0xa4): undefined reference to `PQerrorMessage' ...@@ -6407,13 +6409,14 @@ testlibpq.o(.text+0xa4): undefined reference to `PQerrorMessage'
<title><application>libpq</application> Example Program 1</title> <title><application>libpq</application> Example Program 1</title>
<programlisting> <programlisting>
<![CDATA[
/* /*
* testlibpq.c * testlibpq.c
* *
* Test the C version of libpq, the PostgreSQL frontend library. * Test the C version of libpq, the PostgreSQL frontend library.
*/ */
#include &lt;stdio.h&gt; #include <stdio.h>
#include &lt;stdlib.h&gt; #include <stdlib.h>
#include "libpq-fe.h" #include "libpq-fe.h"
static void static void
...@@ -6438,7 +6441,7 @@ main(int argc, char **argv) ...@@ -6438,7 +6441,7 @@ main(int argc, char **argv)
* conninfo string; otherwise default to setting dbname=postgres and using * conninfo string; otherwise default to setting dbname=postgres and using
* environment variables or defaults for all other connection parameters. * environment variables or defaults for all other connection parameters.
*/ */
if (argc &gt; 1) if (argc > 1)
conninfo = argv[1]; conninfo = argv[1];
else else
conninfo = "dbname = postgres"; conninfo = "dbname = postgres";
...@@ -6498,14 +6501,14 @@ main(int argc, char **argv) ...@@ -6498,14 +6501,14 @@ main(int argc, char **argv)
/* first, print out the attribute names */ /* first, print out the attribute names */
nFields = PQnfields(res); nFields = PQnfields(res);
for (i = 0; i &lt; nFields; i++) for (i = 0; i < nFields; i++)
printf("%-15s", PQfname(res, i)); printf("%-15s", PQfname(res, i));
printf("\n\n"); printf("\n\n");
/* next, print out the rows */ /* next, print out the rows */
for (i = 0; i &lt; PQntuples(res); i++) for (i = 0; i < PQntuples(res); i++)
{ {
for (j = 0; j &lt; nFields; j++) for (j = 0; j < nFields; j++)
printf("%-15s", PQgetvalue(res, i, j)); printf("%-15s", PQgetvalue(res, i, j));
printf("\n"); printf("\n");
} }
...@@ -6525,6 +6528,7 @@ main(int argc, char **argv) ...@@ -6525,6 +6528,7 @@ main(int argc, char **argv)
return 0; return 0;
} }
]]>
</programlisting> </programlisting>
</example> </example>
...@@ -6532,6 +6536,7 @@ main(int argc, char **argv) ...@@ -6532,6 +6536,7 @@ main(int argc, char **argv)
<title><application>libpq</application> Example Program 2</title> <title><application>libpq</application> Example Program 2</title>
<programlisting> <programlisting>
<![CDATA[
/* /*
* testlibpq2.c * testlibpq2.c
* Test of the asynchronous notification interface * Test of the asynchronous notification interface
...@@ -6555,11 +6560,11 @@ main(int argc, char **argv) ...@@ -6555,11 +6560,11 @@ main(int argc, char **argv)
* *
* INSERT INTO TBL1 VALUES (10); * INSERT INTO TBL1 VALUES (10);
*/ */
#include &lt;stdio.h&gt; #include <stdio.h>
#include &lt;stdlib.h&gt; #include <stdlib.h>
#include &lt;string.h&gt; #include <string.h>
#include &lt;errno.h&gt; #include <errno.h>
#include &lt;sys/time.h&gt; #include <sys/time.h>
#include "libpq-fe.h" #include "libpq-fe.h"
static void static void
...@@ -6583,7 +6588,7 @@ main(int argc, char **argv) ...@@ -6583,7 +6588,7 @@ main(int argc, char **argv)
* conninfo string; otherwise default to setting dbname=postgres and using * conninfo string; otherwise default to setting dbname=postgres and using
* environment variables or defaults for all other connection parameters. * environment variables or defaults for all other connection parameters.
*/ */
if (argc &gt; 1) if (argc > 1)
conninfo = argv[1]; conninfo = argv[1];
else else
conninfo = "dbname = postgres"; conninfo = "dbname = postgres";
...@@ -6618,7 +6623,7 @@ main(int argc, char **argv) ...@@ -6618,7 +6623,7 @@ main(int argc, char **argv)
/* Quit after four notifies are received. */ /* Quit after four notifies are received. */
nnotifies = 0; nnotifies = 0;
while (nnotifies &lt; 4) while (nnotifies < 4)
{ {
/* /*
* Sleep until something happens on the connection. We use select(2) * Sleep until something happens on the connection. We use select(2)
...@@ -6630,13 +6635,13 @@ main(int argc, char **argv) ...@@ -6630,13 +6635,13 @@ main(int argc, char **argv)
sock = PQsocket(conn); sock = PQsocket(conn);
if (sock &lt; 0) if (sock < 0)
break; /* shouldn't happen */ break; /* shouldn't happen */
FD_ZERO(&amp;input_mask); FD_ZERO(&input_mask);
FD_SET(sock, &amp;input_mask); FD_SET(sock, &input_mask);
if (select(sock + 1, &amp;input_mask, NULL, NULL, NULL) &lt; 0) if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0)
{ {
fprintf(stderr, "select() failed: %s\n", strerror(errno)); fprintf(stderr, "select() failed: %s\n", strerror(errno));
exit_nicely(conn); exit_nicely(conn);
...@@ -6648,7 +6653,7 @@ main(int argc, char **argv) ...@@ -6648,7 +6653,7 @@ main(int argc, char **argv)
{ {
fprintf(stderr, fprintf(stderr,
"ASYNC NOTIFY of '%s' received from backend pid %d\n", "ASYNC NOTIFY of '%s' received from backend pid %d\n",
notify-&gt;relname, notify-&gt;be_pid); notify->relname, notify->be_pid);
PQfreemem(notify); PQfreemem(notify);
nnotifies++; nnotifies++;
} }
...@@ -6661,6 +6666,7 @@ main(int argc, char **argv) ...@@ -6661,6 +6666,7 @@ main(int argc, char **argv)
return 0; return 0;
} }
]]>
</programlisting> </programlisting>
</example> </example>
...@@ -6668,6 +6674,7 @@ main(int argc, char **argv) ...@@ -6668,6 +6674,7 @@ main(int argc, char **argv)
<title><application>libpq</application> Example Program 3</> <title><application>libpq</application> Example Program 3</>
<programlisting> <programlisting>
<![CDATA[
/* /*
* testlibpq3.c * testlibpq3.c
* Test out-of-line parameters and binary I/O. * Test out-of-line parameters and binary I/O.
...@@ -6692,15 +6699,15 @@ main(int argc, char **argv) ...@@ -6692,15 +6699,15 @@ main(int argc, char **argv)
* t = (8 bytes) 'ho there' * t = (8 bytes) 'ho there'
* b = (5 bytes) \004\003\002\001\000 * b = (5 bytes) \004\003\002\001\000
*/ */
#include &lt;stdio.h&gt; #include <stdio.h>
#include &lt;stdlib.h&gt; #include <stdlib.h>
#include &lt;string.h&gt; #include <string.h>
#include &lt;sys/types.h&gt; #include <sys/types.h>
#include "libpq-fe.h" #include "libpq-fe.h"
/* for ntohl/htonl */ /* for ntohl/htonl */
#include &lt;netinet/in.h&gt; #include <netinet/in.h>
#include &lt;arpa/inet.h&gt; #include <arpa/inet.h>
static void static void
...@@ -6729,7 +6736,7 @@ show_binary_results(PGresult *res) ...@@ -6729,7 +6736,7 @@ show_binary_results(PGresult *res)
t_fnum = PQfnumber(res, "t"); t_fnum = PQfnumber(res, "t");
b_fnum = PQfnumber(res, "b"); b_fnum = PQfnumber(res, "b");
for (i = 0; i &lt; PQntuples(res); i++) for (i = 0; i < PQntuples(res); i++)
{ {
char *iptr; char *iptr;
char *tptr; char *tptr;
...@@ -6764,7 +6771,7 @@ show_binary_results(PGresult *res) ...@@ -6764,7 +6771,7 @@ show_binary_results(PGresult *res)
printf(" t = (%d bytes) '%s'\n", printf(" t = (%d bytes) '%s'\n",
PQgetlength(res, i, t_fnum), tptr); PQgetlength(res, i, t_fnum), tptr);
printf(" b = (%d bytes) ", blen); printf(" b = (%d bytes) ", blen);
for (j = 0; j &lt; blen; j++) for (j = 0; j < blen; j++)
printf("\\%03o", bptr[j]); printf("\\%03o", bptr[j]);
printf("\n\n"); printf("\n\n");
} }
...@@ -6786,7 +6793,7 @@ main(int argc, char **argv) ...@@ -6786,7 +6793,7 @@ main(int argc, char **argv)
* conninfo string; otherwise default to setting dbname=postgres and using * conninfo string; otherwise default to setting dbname=postgres and using
* environment variables or defaults for all other connection parameters. * environment variables or defaults for all other connection parameters.
*/ */
if (argc &gt; 1) if (argc > 1)
conninfo = argv[1]; conninfo = argv[1];
else else
conninfo = "dbname = postgres"; conninfo = "dbname = postgres";
...@@ -6850,7 +6857,7 @@ main(int argc, char **argv) ...@@ -6850,7 +6857,7 @@ main(int argc, char **argv)
binaryIntVal = htonl((uint32_t) 2); binaryIntVal = htonl((uint32_t) 2);
/* Set up parameter arrays for PQexecParams */ /* Set up parameter arrays for PQexecParams */
paramValues[0] = (char *) &amp;binaryIntVal; paramValues[0] = (char *) &binaryIntVal;
paramLengths[0] = sizeof(binaryIntVal); paramLengths[0] = sizeof(binaryIntVal);
paramFormats[0] = 1; /* binary */ paramFormats[0] = 1; /* binary */
...@@ -6879,6 +6886,7 @@ main(int argc, char **argv) ...@@ -6879,6 +6886,7 @@ main(int argc, char **argv)
return 0; return 0;
} }
]]>
</programlisting> </programlisting>
</example> </example>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.48 2008/03/22 01:55:14 ishii Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.49 2008/12/07 23:46:39 alvherre Exp $ -->
<chapter id="largeObjects"> <chapter id="largeObjects">
<title id="largeObjects-title">Large Objects</title> <title id="largeObjects-title">Large Objects</title>
...@@ -457,7 +457,7 @@ SELECT lo_export(image.raster, '/tmp/motd') FROM image ...@@ -457,7 +457,7 @@ SELECT lo_export(image.raster, '/tmp/motd') FROM image
<example id="lo-example"> <example id="lo-example">
<title>Large Objects with <application>libpq</application> Example Program</title> <title>Large Objects with <application>libpq</application> Example Program</title>
<programlisting> <programlisting><![CDATA[
/*-------------------------------------------------------------- /*--------------------------------------------------------------
* *
* testlo.c-- * testlo.c--
...@@ -467,15 +467,15 @@ SELECT lo_export(image.raster, '/tmp/motd') FROM image ...@@ -467,15 +467,15 @@ SELECT lo_export(image.raster, '/tmp/motd') FROM image
* *
*-------------------------------------------------------------- *--------------------------------------------------------------
*/ */
#include &lt;stdio.h&gt; #include <stdio.h>
#include &quot;libpq-fe.h&quot; #include "libpq-fe.h"
#include &quot;libpq/libpq-fs.h&quot; #include "libpq/libpq-fs.h"
#define BUFSIZE 1024 #define BUFSIZE 1024
/* /*
* importFile * importFile
* import file &quot;in_filename&quot; into database as large object &quot;lobjOid&quot; * import file "in_filename" into database as large object "lobjOid"
* *
*/ */
Oid Oid
...@@ -492,9 +492,9 @@ importFile(PGconn *conn, char *filename) ...@@ -492,9 +492,9 @@ importFile(PGconn *conn, char *filename)
* open the file to be read in * open the file to be read in
*/ */
fd = open(filename, O_RDONLY, 0666); fd = open(filename, O_RDONLY, 0666);
if (fd &lt; 0) if (fd < 0)
{ /* error */ { /* error */
fprintf(stderr, &quot;cannot open unix file %s\n&quot;, filename); fprintf(stderr, "cannot open unix file %s\n", filename);
} }
/* /*
...@@ -502,18 +502,18 @@ importFile(PGconn *conn, char *filename) ...@@ -502,18 +502,18 @@ importFile(PGconn *conn, char *filename)
*/ */
lobjId = lo_creat(conn, INV_READ | INV_WRITE); lobjId = lo_creat(conn, INV_READ | INV_WRITE);
if (lobjId == 0) if (lobjId == 0)
fprintf(stderr, &quot;cannot create large object\n&quot;); fprintf(stderr, "cannot create large object\n");
lobj_fd = lo_open(conn, lobjId, INV_WRITE); lobj_fd = lo_open(conn, lobjId, INV_WRITE);
/* /*
* read in from the Unix file and write to the inversion file * read in from the Unix file and write to the inversion file
*/ */
while ((nbytes = read(fd, buf, BUFSIZE)) &gt; 0) while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
{ {
tmp = lo_write(conn, lobj_fd, buf, nbytes); tmp = lo_write(conn, lobj_fd, buf, nbytes);
if (tmp &lt; nbytes) if (tmp < nbytes)
fprintf(stderr, &quot;error while reading large object\n&quot;); fprintf(stderr, "error while reading large object\n");
} }
(void) close(fd); (void) close(fd);
...@@ -531,9 +531,9 @@ pickout(PGconn *conn, Oid lobjId, int start, int len) ...@@ -531,9 +531,9 @@ pickout(PGconn *conn, Oid lobjId, int start, int len)
int nread; int nread;
lobj_fd = lo_open(conn, lobjId, INV_READ); lobj_fd = lo_open(conn, lobjId, INV_READ);
if (lobj_fd &lt; 0) if (lobj_fd < 0)
{ {
fprintf(stderr, &quot;cannot open large object %d\n&quot;, fprintf(stderr, "cannot open large object %d\n",
lobjId); lobjId);
} }
...@@ -541,15 +541,15 @@ pickout(PGconn *conn, Oid lobjId, int start, int len) ...@@ -541,15 +541,15 @@ pickout(PGconn *conn, Oid lobjId, int start, int len)
buf = malloc(len + 1); buf = malloc(len + 1);
nread = 0; nread = 0;
while (len - nread &gt; 0) while (len - nread > 0)
{ {
nbytes = lo_read(conn, lobj_fd, buf, len - nread); nbytes = lo_read(conn, lobj_fd, buf, len - nread);
buf[nbytes] = ' '; buf[nbytes] = ' ';
fprintf(stderr, &quot;&gt;&gt;&gt; %s&quot;, buf); fprintf(stderr, ">>> %s", buf);
nread += nbytes; nread += nbytes;
} }
free(buf); free(buf);
fprintf(stderr, &quot;\n&quot;); fprintf(stderr, "\n");
lo_close(conn, lobj_fd); lo_close(conn, lobj_fd);
} }
...@@ -563,33 +563,33 @@ overwrite(PGconn *conn, Oid lobjId, int start, int len) ...@@ -563,33 +563,33 @@ overwrite(PGconn *conn, Oid lobjId, int start, int len)
int i; int i;
lobj_fd = lo_open(conn, lobjId, INV_WRITE); lobj_fd = lo_open(conn, lobjId, INV_WRITE);
if (lobj_fd &lt; 0) if (lobj_fd < 0)
{ {
fprintf(stderr, &quot;cannot open large object %d\n&quot;, fprintf(stderr, "cannot open large object %d\n",
lobjId); lobjId);
} }
lo_lseek(conn, lobj_fd, start, SEEK_SET); lo_lseek(conn, lobj_fd, start, SEEK_SET);
buf = malloc(len + 1); buf = malloc(len + 1);
for (i = 0; i &lt; len; i++) for (i = 0; i < len; i++)
buf[i] = 'X'; buf[i] = 'X';
buf[i] = ' '; buf[i] = ' ';
nwritten = 0; nwritten = 0;
while (len - nwritten &gt; 0) while (len - nwritten > 0)
{ {
nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten); nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
nwritten += nbytes; nwritten += nbytes;
} }
free(buf); free(buf);
fprintf(stderr, &quot;\n&quot;); fprintf(stderr, "\n");
lo_close(conn, lobj_fd); lo_close(conn, lobj_fd);
} }
/* /*
* exportFile * exportFile
* export large object &quot;lobjOid&quot; to file &quot;out_filename&quot; * export large object "lobjOid" to file "out_filename"
* *
*/ */
void void
...@@ -605,9 +605,9 @@ exportFile(PGconn *conn, Oid lobjId, char *filename) ...@@ -605,9 +605,9 @@ exportFile(PGconn *conn, Oid lobjId, char *filename)
* open the large object * open the large object
*/ */
lobj_fd = lo_open(conn, lobjId, INV_READ); lobj_fd = lo_open(conn, lobjId, INV_READ);
if (lobj_fd &lt; 0) if (lobj_fd < 0)
{ {
fprintf(stderr, &quot;cannot open large object %d\n&quot;, fprintf(stderr, "cannot open large object %d\n",
lobjId); lobjId);
} }
...@@ -615,21 +615,21 @@ exportFile(PGconn *conn, Oid lobjId, char *filename) ...@@ -615,21 +615,21 @@ exportFile(PGconn *conn, Oid lobjId, char *filename)
* open the file to be written to * open the file to be written to
*/ */
fd = open(filename, O_CREAT | O_WRONLY, 0666); fd = open(filename, O_CREAT | O_WRONLY, 0666);
if (fd &lt; 0) if (fd < 0)
{ /* error */ { /* error */
fprintf(stderr, &quot;cannot open unix file %s\n&quot;, fprintf(stderr, "cannot open unix file %s\n",
filename); filename);
} }
/* /*
* read in from the inversion file and write to the Unix file * read in from the inversion file and write to the Unix file
*/ */
while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) &gt; 0) while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
{ {
tmp = write(fd, buf, nbytes); tmp = write(fd, buf, nbytes);
if (tmp &lt; nbytes) if (tmp < nbytes)
{ {
fprintf(stderr, &quot;error while writing %s\n&quot;, fprintf(stderr, "error while writing %s\n",
filename); filename);
} }
} }
...@@ -659,7 +659,7 @@ main(int argc, char **argv) ...@@ -659,7 +659,7 @@ main(int argc, char **argv)
if (argc != 4) if (argc != 4)
{ {
fprintf(stderr, &quot;Usage: %s database_name in_filename out_filename\n&quot;, fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
argv[0]); argv[0]);
exit(1); exit(1);
} }
...@@ -676,36 +676,37 @@ main(int argc, char **argv) ...@@ -676,36 +676,37 @@ main(int argc, char **argv)
/* check to see that the backend connection was successfully made */ /* check to see that the backend connection was successfully made */
if (PQstatus(conn) == CONNECTION_BAD) if (PQstatus(conn) == CONNECTION_BAD)
{ {
fprintf(stderr, &quot;Connection to database '%s' failed.\n&quot;, database); fprintf(stderr, "Connection to database '%s' failed.\n", database);
fprintf(stderr, &quot;%s&quot;, PQerrorMessage(conn)); fprintf(stderr, "%s", PQerrorMessage(conn));
exit_nicely(conn); exit_nicely(conn);
} }
res = PQexec(conn, &quot;begin&quot;); res = PQexec(conn, "begin");
PQclear(res); PQclear(res);
printf(&quot;importing file %s\n&quot;, in_filename); printf("importing file %s\n", in_filename);
/* lobjOid = importFile(conn, in_filename); */ /* lobjOid = importFile(conn, in_filename); */
lobjOid = lo_import(conn, in_filename); lobjOid = lo_import(conn, in_filename);
/* /*
printf(&quot;as large object %d.\n&quot;, lobjOid); printf("as large object %d.\n", lobjOid);
printf(&quot;picking out bytes 1000-2000 of the large object\n&quot;); printf("picking out bytes 1000-2000 of the large object\n");
pickout(conn, lobjOid, 1000, 1000); pickout(conn, lobjOid, 1000, 1000);
printf(&quot;overwriting bytes 1000-2000 of the large object with X's\n&quot;); printf("overwriting bytes 1000-2000 of the large object with X's\n");
overwrite(conn, lobjOid, 1000, 1000); overwrite(conn, lobjOid, 1000, 1000);
*/ */
printf(&quot;exporting large object to file %s\n&quot;, out_filename); printf("exporting large object to file %s\n", out_filename);
/* exportFile(conn, lobjOid, out_filename); */ /* exportFile(conn, lobjOid, out_filename); */
lo_export(conn, lobjOid, out_filename); lo_export(conn, lobjOid, out_filename);
res = PQexec(conn, &quot;end&quot;); res = PQexec(conn, "end");
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
exit(0); exit(0);
} }
]]>
</programlisting> </programlisting>
</example> </example>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.52 2008/03/28 00:21:55 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.53 2008/12/07 23:46:39 alvherre Exp $ -->
<chapter id="triggers"> <chapter id="triggers">
<title>Triggers</title> <title>Triggers</title>
...@@ -559,7 +559,7 @@ CREATE TABLE ttest ( ...@@ -559,7 +559,7 @@ CREATE TABLE ttest (
<para> <para>
This is the source code of the trigger function: This is the source code of the trigger function:
<programlisting> <programlisting><![CDATA[
#include "postgres.h" #include "postgres.h"
#include "executor/spi.h" /* this is what you need to work with SPI */ #include "executor/spi.h" /* this is what you need to work with SPI */
#include "commands/trigger.h" /* ... and triggers */ #include "commands/trigger.h" /* ... and triggers */
...@@ -571,7 +571,7 @@ PG_FUNCTION_INFO_V1(trigf); ...@@ -571,7 +571,7 @@ PG_FUNCTION_INFO_V1(trigf);
Datum Datum
trigf(PG_FUNCTION_ARGS) trigf(PG_FUNCTION_ARGS)
{ {
TriggerData *trigdata = (TriggerData *) fcinfo-&gt;context; TriggerData *trigdata = (TriggerData *) fcinfo->context;
TupleDesc tupdesc; TupleDesc tupdesc;
HeapTuple rettuple; HeapTuple rettuple;
char *when; char *when;
...@@ -584,38 +584,38 @@ trigf(PG_FUNCTION_ARGS) ...@@ -584,38 +584,38 @@ trigf(PG_FUNCTION_ARGS)
elog(ERROR, "trigf: not called by trigger manager"); elog(ERROR, "trigf: not called by trigger manager");
/* tuple to return to executor */ /* tuple to return to executor */
if (TRIGGER_FIRED_BY_UPDATE(trigdata-&gt;tg_event)) if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
rettuple = trigdata-&gt;tg_newtuple; rettuple = trigdata->tg_newtuple;
else else
rettuple = trigdata-&gt;tg_trigtuple; rettuple = trigdata->tg_trigtuple;
/* check for null values */ /* check for null values */
if (!TRIGGER_FIRED_BY_DELETE(trigdata-&gt;tg_event) if (!TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)
&amp;&amp; TRIGGER_FIRED_BEFORE(trigdata-&gt;tg_event)) && TRIGGER_FIRED_BEFORE(trigdata->tg_event))
checknull = true; checknull = true;
if (TRIGGER_FIRED_BEFORE(trigdata-&gt;tg_event)) if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
when = "before"; when = "before";
else else
when = "after "; when = "after ";
tupdesc = trigdata-&gt;tg_relation-&gt;rd_att; tupdesc = trigdata->tg_relation->rd_att;
/* connect to SPI manager */ /* connect to SPI manager */
if ((ret = SPI_connect()) &lt; 0) if ((ret = SPI_connect()) < 0)
elog(INFO, "trigf (fired %s): SPI_connect returned %d", when, ret); elog(INFO, "trigf (fired %s): SPI_connect returned %d", when, ret);
/* get number of rows in table */ /* get number of rows in table */
ret = SPI_exec("SELECT count(*) FROM ttest", 0); ret = SPI_exec("SELECT count(*) FROM ttest", 0);
if (ret &lt; 0) if (ret < 0)
elog(NOTICE, "trigf (fired %s): SPI_exec returned %d", when, ret); elog(NOTICE, "trigf (fired %s): SPI_exec returned %d", when, ret);
/* count(*) returns int8, so be careful to convert */ /* count(*) returns int8, so be careful to convert */
i = DatumGetInt64(SPI_getbinval(SPI_tuptable-&gt;vals[0], i = DatumGetInt64(SPI_getbinval(SPI_tuptable->vals[0],
SPI_tuptable-&gt;tupdesc, SPI_tuptable->tupdesc,
1, 1,
&amp;isnull)); &isnull));
elog (INFO, "trigf (fired %s): there are %d rows in ttest", when, i); elog (INFO, "trigf (fired %s): there are %d rows in ttest", when, i);
...@@ -623,13 +623,14 @@ trigf(PG_FUNCTION_ARGS) ...@@ -623,13 +623,14 @@ trigf(PG_FUNCTION_ARGS)
if (checknull) if (checknull)
{ {
SPI_getbinval(rettuple, tupdesc, 1, &amp;isnull); SPI_getbinval(rettuple, tupdesc, 1, &isnull);
if (isnull) if (isnull)
rettuple = NULL; rettuple = NULL;
} }
return PointerGetDatum(rettuple); return PointerGetDatum(rettuple);
} }
]]>
</programlisting> </programlisting>
</para> </para>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.134 2008/12/04 17:51:26 petere Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.135 2008/12/07 23:46:39 alvherre Exp $ -->
<sect1 id="xfunc"> <sect1 id="xfunc">
<title>User-Defined Functions</title> <title>User-Defined Functions</title>
...@@ -1621,15 +1621,16 @@ typedef struct { ...@@ -1621,15 +1621,16 @@ typedef struct {
For example, if we wanted to store 40 bytes in a <structname>text</> For example, if we wanted to store 40 bytes in a <structname>text</>
structure, we might use a code fragment like this: structure, we might use a code fragment like this:
<programlisting> <programlisting><![CDATA[
#include "postgres.h" #include "postgres.h"
... ...
char buffer[40]; /* our source data */ char buffer[40]; /* our source data */
... ...
text *destination = (text *) palloc(VARHDRSZ + 40); text *destination = (text *) palloc(VARHDRSZ + 40);
destination-&gt;length = VARHDRSZ + 40; destination->length = VARHDRSZ + 40;
memcpy(destination-&gt;data, buffer, 40); memcpy(destination->data, buffer, 40);
... ...
]]>
</programlisting> </programlisting>
<literal>VARHDRSZ</> is the same as <literal>sizeof(int4)</>, but <literal>VARHDRSZ</> is the same as <literal>sizeof(int4)</>, but
...@@ -1842,9 +1843,9 @@ memcpy(destination-&gt;data, buffer, 40); ...@@ -1842,9 +1843,9 @@ memcpy(destination-&gt;data, buffer, 40);
<para> <para>
Here are some examples: Here are some examples:
<programlisting> <programlisting><![CDATA[
#include "postgres.h" #include "postgres.h"
#include &lt;string.h&gt; #include <string.h>
/* by value */ /* by value */
...@@ -1871,8 +1872,8 @@ makepoint(Point *pointx, Point *pointy) ...@@ -1871,8 +1872,8 @@ makepoint(Point *pointx, Point *pointy)
{ {
Point *new_point = (Point *) palloc(sizeof(Point)); Point *new_point = (Point *) palloc(sizeof(Point));
new_point-&gt;x = pointx-&gt;x; new_point->x = pointx->x;
new_point-&gt;y = pointy-&gt;y; new_point->y = pointy->y;
return new_point; return new_point;
} }
...@@ -1908,6 +1909,7 @@ concat_text(text *arg1, text *arg2) ...@@ -1908,6 +1909,7 @@ concat_text(text *arg1, text *arg2)
VARDATA(arg2), VARSIZE(arg2) - VARHDRSZ); VARDATA(arg2), VARSIZE(arg2) - VARHDRSZ);
return new_text; return new_text;
} }
]]>
</programlisting> </programlisting>
</para> </para>
...@@ -2014,9 +2016,9 @@ PG_FUNCTION_INFO_V1(funcname); ...@@ -2014,9 +2016,9 @@ PG_FUNCTION_INFO_V1(funcname);
<para> <para>
Here we show the same functions as above, coded in version-1 style: Here we show the same functions as above, coded in version-1 style:
<programlisting> <programlisting><![CDATA[
#include "postgres.h" #include "postgres.h"
#include &lt;string.h&gt; #include <string.h>
#include "fmgr.h" #include "fmgr.h"
/* by value */ /* by value */
...@@ -2054,8 +2056,8 @@ makepoint(PG_FUNCTION_ARGS) ...@@ -2054,8 +2056,8 @@ makepoint(PG_FUNCTION_ARGS)
Point *pointy = PG_GETARG_POINT_P(1); Point *pointy = PG_GETARG_POINT_P(1);
Point *new_point = (Point *) palloc(sizeof(Point)); Point *new_point = (Point *) palloc(sizeof(Point));
new_point-&gt;x = pointx-&gt;x; new_point->x = pointx->x;
new_point-&gt;y = pointy-&gt;y; new_point->y = pointy->y;
PG_RETURN_POINT_P(new_point); PG_RETURN_POINT_P(new_point);
} }
...@@ -2098,6 +2100,7 @@ concat_text(PG_FUNCTION_ARGS) ...@@ -2098,6 +2100,7 @@ concat_text(PG_FUNCTION_ARGS)
VARDATA(arg2), VARSIZE(arg2) - VARHDRSZ); VARDATA(arg2), VARSIZE(arg2) - VARHDRSZ);
PG_RETURN_TEXT_P(new_text); PG_RETURN_TEXT_P(new_text);
} }
]]>
</programlisting> </programlisting>
</para> </para>
...@@ -2552,7 +2555,7 @@ SELECT name, c_overpaid(emp, 1500) AS overpaid ...@@ -2552,7 +2555,7 @@ SELECT name, c_overpaid(emp, 1500) AS overpaid
Using call conventions version 0, we can define Using call conventions version 0, we can define
<function>c_overpaid</> as: <function>c_overpaid</> as:
<programlisting> <programlisting><![CDATA[
#include "postgres.h" #include "postgres.h"
#include "executor/executor.h" /* for GetAttributeByName() */ #include "executor/executor.h" /* for GetAttributeByName() */
...@@ -2563,16 +2566,17 @@ c_overpaid(HeapTupleHeader t, /* the current row of emp */ ...@@ -2563,16 +2566,17 @@ c_overpaid(HeapTupleHeader t, /* the current row of emp */
bool isnull; bool isnull;
int32 salary; int32 salary;
salary = DatumGetInt32(GetAttributeByName(t, "salary", &amp;isnull)); salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
if (isnull) if (isnull)
return false; return false;
return salary &gt; limit; return salary > limit;
} }
]]>
</programlisting> </programlisting>
In version-1 coding, the above would look like this: In version-1 coding, the above would look like this:
<programlisting> <programlisting><![CDATA[
#include "postgres.h" #include "postgres.h"
#include "executor/executor.h" /* for GetAttributeByName() */ #include "executor/executor.h" /* for GetAttributeByName() */
...@@ -2586,13 +2590,14 @@ c_overpaid(PG_FUNCTION_ARGS) ...@@ -2586,13 +2590,14 @@ c_overpaid(PG_FUNCTION_ARGS)
bool isnull; bool isnull;
Datum salary; Datum salary;
salary = GetAttributeByName(t, "salary", &amp;isnull); salary = GetAttributeByName(t, "salary", &isnull);
if (isnull) if (isnull)
PG_RETURN_BOOL(false); PG_RETURN_BOOL(false);
/* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary. */ /* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary. */
PG_RETURN_BOOL(DatumGetInt32(salary) &gt; limit); PG_RETURN_BOOL(DatumGetInt32(salary) > limit);
} }
]]>
</programlisting> </programlisting>
</para> </para>
...@@ -2974,7 +2979,7 @@ my_set_returning_function(PG_FUNCTION_ARGS) ...@@ -2974,7 +2979,7 @@ my_set_returning_function(PG_FUNCTION_ARGS)
<para> <para>
A complete example of a simple <acronym>SRF</> returning a composite type A complete example of a simple <acronym>SRF</> returning a composite type
looks like: looks like:
<programlisting> <programlisting><![CDATA[
PG_FUNCTION_INFO_V1(retcomposite); PG_FUNCTION_INFO_V1(retcomposite);
Datum Datum
...@@ -2995,13 +3000,13 @@ retcomposite(PG_FUNCTION_ARGS) ...@@ -2995,13 +3000,13 @@ retcomposite(PG_FUNCTION_ARGS)
funcctx = SRF_FIRSTCALL_INIT(); funcctx = SRF_FIRSTCALL_INIT();
/* switch to memory context appropriate for multiple function calls */ /* switch to memory context appropriate for multiple function calls */
oldcontext = MemoryContextSwitchTo(funcctx-&gt;multi_call_memory_ctx); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
/* total number of tuples to be returned */ /* total number of tuples to be returned */
funcctx-&gt;max_calls = PG_GETARG_UINT32(0); funcctx->max_calls = PG_GETARG_UINT32(0);
/* Build a tuple descriptor for our result type */ /* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &amp;tupdesc) != TYPEFUNC_COMPOSITE) if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("function returning record called in context " errmsg("function returning record called in context "
...@@ -3012,7 +3017,7 @@ retcomposite(PG_FUNCTION_ARGS) ...@@ -3012,7 +3017,7 @@ retcomposite(PG_FUNCTION_ARGS)
* C strings * C strings
*/ */
attinmeta = TupleDescGetAttInMetadata(tupdesc); attinmeta = TupleDescGetAttInMetadata(tupdesc);
funcctx-&gt;attinmeta = attinmeta; funcctx->attinmeta = attinmeta;
MemoryContextSwitchTo(oldcontext); MemoryContextSwitchTo(oldcontext);
} }
...@@ -3020,11 +3025,11 @@ retcomposite(PG_FUNCTION_ARGS) ...@@ -3020,11 +3025,11 @@ retcomposite(PG_FUNCTION_ARGS)
/* stuff done on every call of the function */ /* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP(); funcctx = SRF_PERCALL_SETUP();
call_cntr = funcctx-&gt;call_cntr; call_cntr = funcctx->call_cntr;
max_calls = funcctx-&gt;max_calls; max_calls = funcctx->max_calls;
attinmeta = funcctx-&gt;attinmeta; attinmeta = funcctx->attinmeta;
if (call_cntr &lt; max_calls) /* do when there is more left to send */ if (call_cntr < max_calls) /* do when there is more left to send */
{ {
char **values; char **values;
HeapTuple tuple; HeapTuple tuple;
...@@ -3063,6 +3068,7 @@ retcomposite(PG_FUNCTION_ARGS) ...@@ -3063,6 +3068,7 @@ retcomposite(PG_FUNCTION_ARGS)
SRF_RETURN_DONE(funcctx); SRF_RETURN_DONE(funcctx);
} }
} }
]]>
</programlisting> </programlisting>
One way to declare this function in SQL is: One way to declare this function in SQL is:
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.63 2008/05/16 16:31:01 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.64 2008/12/07 23:46:39 alvherre Exp $ -->
<sect1 id="xindex"> <sect1 id="xindex">
<title>Interfacing Extensions To Indexes</title> <title>Interfacing Extensions To Indexes</title>
...@@ -499,8 +499,8 @@ ...@@ -499,8 +499,8 @@
reduces the odds of getting inconsistent results for corner cases. reduces the odds of getting inconsistent results for corner cases.
Following this approach, we first write: Following this approach, we first write:
<programlisting> <programlisting><![CDATA[
#define Mag(c) ((c)-&gt;x*(c)-&gt;x + (c)-&gt;y*(c)-&gt;y) #define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
static int static int
complex_abs_cmp_internal(Complex *a, Complex *b) complex_abs_cmp_internal(Complex *a, Complex *b)
...@@ -508,17 +508,18 @@ complex_abs_cmp_internal(Complex *a, Complex *b) ...@@ -508,17 +508,18 @@ complex_abs_cmp_internal(Complex *a, Complex *b)
double amag = Mag(a), double amag = Mag(a),
bmag = Mag(b); bmag = Mag(b);
if (amag &lt; bmag) if (amag < bmag)
return -1; return -1;
if (amag &gt; bmag) if (amag > bmag)
return 1; return 1;
return 0; return 0;
} }
]]>
</programlisting> </programlisting>
Now the less-than function looks like: Now the less-than function looks like:
<programlisting> <programlisting><![CDATA[
PG_FUNCTION_INFO_V1(complex_abs_lt); PG_FUNCTION_INFO_V1(complex_abs_lt);
Datum Datum
...@@ -527,8 +528,9 @@ complex_abs_lt(PG_FUNCTION_ARGS) ...@@ -527,8 +528,9 @@ complex_abs_lt(PG_FUNCTION_ARGS)
Complex *a = (Complex *) PG_GETARG_POINTER(0); Complex *a = (Complex *) PG_GETARG_POINTER(0);
Complex *b = (Complex *) PG_GETARG_POINTER(1); Complex *b = (Complex *) PG_GETARG_POINTER(1);
PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) &lt; 0); PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) < 0);
} }
]]>
</programlisting> </programlisting>
The other four functions differ only in how they compare the internal The other four functions differ only in how they compare the internal
...@@ -617,15 +619,16 @@ CREATE FUNCTION complex_abs_cmp(complex, complex) ...@@ -617,15 +619,16 @@ CREATE FUNCTION complex_abs_cmp(complex, complex)
Now that we have the required operators and support routine, Now that we have the required operators and support routine,
we can finally create the operator class: we can finally create the operator class:
<programlisting> <programlisting><![CDATA[
CREATE OPERATOR CLASS complex_abs_ops CREATE OPERATOR CLASS complex_abs_ops
DEFAULT FOR TYPE complex USING btree AS DEFAULT FOR TYPE complex USING btree AS
OPERATOR 1 &lt; , OPERATOR 1 < ,
OPERATOR 2 &lt;= , OPERATOR 2 <= ,
OPERATOR 3 = , OPERATOR 3 = ,
OPERATOR 4 &gt;= , OPERATOR 4 >= ,
OPERATOR 5 &gt; , OPERATOR 5 > ,
FUNCTION 1 complex_abs_cmp(complex, complex); FUNCTION 1 complex_abs_cmp(complex, complex);
]]>
</programlisting> </programlisting>
</para> </para>
...@@ -708,87 +711,88 @@ CREATE OPERATOR CLASS complex_abs_ops ...@@ -708,87 +711,88 @@ CREATE OPERATOR CLASS complex_abs_ops
on one of these types can be searched using a comparison value of another on one of these types can be searched using a comparison value of another
type. The family could be duplicated by these definitions: type. The family could be duplicated by these definitions:
<programlisting> <programlisting><![CDATA[
CREATE OPERATOR FAMILY integer_ops USING btree; CREATE OPERATOR FAMILY integer_ops USING btree;
CREATE OPERATOR CLASS int8_ops CREATE OPERATOR CLASS int8_ops
DEFAULT FOR TYPE int8 USING btree FAMILY integer_ops AS DEFAULT FOR TYPE int8 USING btree FAMILY integer_ops AS
-- standard int8 comparisons -- standard int8 comparisons
OPERATOR 1 &lt; , OPERATOR 1 < ,
OPERATOR 2 &lt;= , OPERATOR 2 <= ,
OPERATOR 3 = , OPERATOR 3 = ,
OPERATOR 4 &gt;= , OPERATOR 4 >= ,
OPERATOR 5 &gt; , OPERATOR 5 > ,
FUNCTION 1 btint8cmp(int8, int8) ; FUNCTION 1 btint8cmp(int8, int8) ;
CREATE OPERATOR CLASS int4_ops CREATE OPERATOR CLASS int4_ops
DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS
-- standard int4 comparisons -- standard int4 comparisons
OPERATOR 1 &lt; , OPERATOR 1 < ,
OPERATOR 2 &lt;= , OPERATOR 2 <= ,
OPERATOR 3 = , OPERATOR 3 = ,
OPERATOR 4 &gt;= , OPERATOR 4 >= ,
OPERATOR 5 &gt; , OPERATOR 5 > ,
FUNCTION 1 btint4cmp(int4, int4) ; FUNCTION 1 btint4cmp(int4, int4) ;
CREATE OPERATOR CLASS int2_ops CREATE OPERATOR CLASS int2_ops
DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS
-- standard int2 comparisons -- standard int2 comparisons
OPERATOR 1 &lt; , OPERATOR 1 < ,
OPERATOR 2 &lt;= , OPERATOR 2 <= ,
OPERATOR 3 = , OPERATOR 3 = ,
OPERATOR 4 &gt;= , OPERATOR 4 >= ,
OPERATOR 5 &gt; , OPERATOR 5 > ,
FUNCTION 1 btint2cmp(int2, int2) ; FUNCTION 1 btint2cmp(int2, int2) ;
ALTER OPERATOR FAMILY integer_ops USING btree ADD ALTER OPERATOR FAMILY integer_ops USING btree ADD
-- cross-type comparisons int8 vs int2 -- cross-type comparisons int8 vs int2
OPERATOR 1 &lt; (int8, int2) , OPERATOR 1 < (int8, int2) ,
OPERATOR 2 &lt;= (int8, int2) , OPERATOR 2 <= (int8, int2) ,
OPERATOR 3 = (int8, int2) , OPERATOR 3 = (int8, int2) ,
OPERATOR 4 &gt;= (int8, int2) , OPERATOR 4 >= (int8, int2) ,
OPERATOR 5 &gt; (int8, int2) , OPERATOR 5 > (int8, int2) ,
FUNCTION 1 btint82cmp(int8, int2) , FUNCTION 1 btint82cmp(int8, int2) ,
-- cross-type comparisons int8 vs int4 -- cross-type comparisons int8 vs int4
OPERATOR 1 &lt; (int8, int4) , OPERATOR 1 < (int8, int4) ,
OPERATOR 2 &lt;= (int8, int4) , OPERATOR 2 <= (int8, int4) ,
OPERATOR 3 = (int8, int4) , OPERATOR 3 = (int8, int4) ,
OPERATOR 4 &gt;= (int8, int4) , OPERATOR 4 >= (int8, int4) ,
OPERATOR 5 &gt; (int8, int4) , OPERATOR 5 > (int8, int4) ,
FUNCTION 1 btint84cmp(int8, int4) , FUNCTION 1 btint84cmp(int8, int4) ,
-- cross-type comparisons int4 vs int2 -- cross-type comparisons int4 vs int2
OPERATOR 1 &lt; (int4, int2) , OPERATOR 1 < (int4, int2) ,
OPERATOR 2 &lt;= (int4, int2) , OPERATOR 2 <= (int4, int2) ,
OPERATOR 3 = (int4, int2) , OPERATOR 3 = (int4, int2) ,
OPERATOR 4 &gt;= (int4, int2) , OPERATOR 4 >= (int4, int2) ,
OPERATOR 5 &gt; (int4, int2) , OPERATOR 5 > (int4, int2) ,
FUNCTION 1 btint42cmp(int4, int2) , FUNCTION 1 btint42cmp(int4, int2) ,
-- cross-type comparisons int4 vs int8 -- cross-type comparisons int4 vs int8
OPERATOR 1 &lt; (int4, int8) , OPERATOR 1 < (int4, int8) ,
OPERATOR 2 &lt;= (int4, int8) , OPERATOR 2 <= (int4, int8) ,
OPERATOR 3 = (int4, int8) , OPERATOR 3 = (int4, int8) ,
OPERATOR 4 &gt;= (int4, int8) , OPERATOR 4 >= (int4, int8) ,
OPERATOR 5 &gt; (int4, int8) , OPERATOR 5 > (int4, int8) ,
FUNCTION 1 btint48cmp(int4, int8) , FUNCTION 1 btint48cmp(int4, int8) ,
-- cross-type comparisons int2 vs int8 -- cross-type comparisons int2 vs int8
OPERATOR 1 &lt; (int2, int8) , OPERATOR 1 < (int2, int8) ,
OPERATOR 2 &lt;= (int2, int8) , OPERATOR 2 <= (int2, int8) ,
OPERATOR 3 = (int2, int8) , OPERATOR 3 = (int2, int8) ,
OPERATOR 4 &gt;= (int2, int8) , OPERATOR 4 >= (int2, int8) ,
OPERATOR 5 &gt; (int2, int8) , OPERATOR 5 > (int2, int8) ,
FUNCTION 1 btint28cmp(int2, int8) , FUNCTION 1 btint28cmp(int2, int8) ,
-- cross-type comparisons int2 vs int4 -- cross-type comparisons int2 vs int4
OPERATOR 1 &lt; (int2, int4) , OPERATOR 1 < (int2, int4) ,
OPERATOR 2 &lt;= (int2, int4) , OPERATOR 2 <= (int2, int4) ,
OPERATOR 3 = (int2, int4) , OPERATOR 3 = (int2, int4) ,
OPERATOR 4 &gt;= (int2, int4) , OPERATOR 4 >= (int2, int4) ,
OPERATOR 5 &gt; (int2, int4) , OPERATOR 5 > (int2, int4) ,
FUNCTION 1 btint24cmp(int2, int4) ; FUNCTION 1 btint24cmp(int2, int4) ;
]]>
</programlisting> </programlisting>
Notice that this definition <quote>overloads</> the operator strategy and Notice that this definition <quote>overloads</> the operator strategy and
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/xtypes.sgml,v 1.30 2008/02/23 19:11:45 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/xtypes.sgml,v 1.31 2008/12/07 23:46:39 alvherre Exp $ -->
<sect1 id="xtypes"> <sect1 id="xtypes">
<title>User-Defined Types</title> <title>User-Defined Types</title>
...@@ -75,7 +75,7 @@ typedef struct Complex { ...@@ -75,7 +75,7 @@ typedef struct Complex {
write a complete and robust parser for that representation as your write a complete and robust parser for that representation as your
input function. For instance: input function. For instance:
<programlisting> <programlisting><![CDATA[
PG_FUNCTION_INFO_V1(complex_in); PG_FUNCTION_INFO_V1(complex_in);
Datum Datum
...@@ -86,22 +86,23 @@ complex_in(PG_FUNCTION_ARGS) ...@@ -86,22 +86,23 @@ complex_in(PG_FUNCTION_ARGS)
y; y;
Complex *result; Complex *result;
if (sscanf(str, " ( %lf , %lf )", &amp;x, &amp;y) != 2) if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for complex: \"%s\"", errmsg("invalid input syntax for complex: \"%s\"",
str))); str)));
result = (Complex *) palloc(sizeof(Complex)); result = (Complex *) palloc(sizeof(Complex));
result-&gt;x = x; result->x = x;
result-&gt;y = y; result->y = y;
PG_RETURN_POINTER(result); PG_RETURN_POINTER(result);
} }
]]>
</programlisting> </programlisting>
The output function can simply be: The output function can simply be:
<programlisting> <programlisting><![CDATA[
PG_FUNCTION_INFO_V1(complex_out); PG_FUNCTION_INFO_V1(complex_out);
Datum Datum
...@@ -111,9 +112,10 @@ complex_out(PG_FUNCTION_ARGS) ...@@ -111,9 +112,10 @@ complex_out(PG_FUNCTION_ARGS)
char *result; char *result;
result = (char *) palloc(100); result = (char *) palloc(100);
snprintf(result, 100, "(%g,%g)", complex-&gt;x, complex-&gt;y); snprintf(result, 100, "(%g,%g)", complex->x, complex->y);
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
]]>
</programlisting> </programlisting>
</para> </para>
...@@ -134,7 +136,7 @@ complex_out(PG_FUNCTION_ARGS) ...@@ -134,7 +136,7 @@ complex_out(PG_FUNCTION_ARGS)
<type>complex</type>, we will piggy-back on the binary I/O converters <type>complex</type>, we will piggy-back on the binary I/O converters
for type <type>float8</>: for type <type>float8</>:
<programlisting> <programlisting><![CDATA[
PG_FUNCTION_INFO_V1(complex_recv); PG_FUNCTION_INFO_V1(complex_recv);
Datum Datum
...@@ -144,8 +146,8 @@ complex_recv(PG_FUNCTION_ARGS) ...@@ -144,8 +146,8 @@ complex_recv(PG_FUNCTION_ARGS)
Complex *result; Complex *result;
result = (Complex *) palloc(sizeof(Complex)); result = (Complex *) palloc(sizeof(Complex));
result-&gt;x = pq_getmsgfloat8(buf); result->x = pq_getmsgfloat8(buf);
result-&gt;y = pq_getmsgfloat8(buf); result->y = pq_getmsgfloat8(buf);
PG_RETURN_POINTER(result); PG_RETURN_POINTER(result);
} }
...@@ -157,11 +159,12 @@ complex_send(PG_FUNCTION_ARGS) ...@@ -157,11 +159,12 @@ complex_send(PG_FUNCTION_ARGS)
Complex *complex = (Complex *) PG_GETARG_POINTER(0); Complex *complex = (Complex *) PG_GETARG_POINTER(0);
StringInfoData buf; StringInfoData buf;
pq_begintypsend(&amp;buf); pq_begintypsend(&buf);
pq_sendfloat8(&amp;buf, complex-&gt;x); pq_sendfloat8(&buf, complex->x);
pq_sendfloat8(&amp;buf, complex-&gt;y); pq_sendfloat8(&buf, complex->y);
PG_RETURN_BYTEA_P(pq_endtypsend(&amp;buf)); PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
} }
]]>
</programlisting> </programlisting>
</para> </para>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment