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