</ListItem>
<ListItem>
<Para>
-<Acronym>tty</Acronym> -- file or tty for optional debug output.
+<Acronym>tty</Acronym> -- file or tty for optional debug output from backend.
</Para>
</ListItem>
</ItemizedList>
PQconninfoOption *PQconndefaults(void)
struct PQconninfoOption
- {
- char *keyword; /* The keyword of the option */
- char *envvar; /* Fallback environment variable name */
- char *compiled; /* Fallback compiled in default value */
- char *val; /* Options value */
- char *label; /* Label for field in connect dialog */
- char *dispchar; /* Character to display for this field
- in a connect dialog. Values are:
- "" Display entered value as is
- "*" Password field - hide value
- "D" Debug options - don't
- create a field by default */
- int dispsize; /* Field size in characters for dialog */
- };
+ {
+ char *keyword; /* The keyword of the option */
+ char *envvar; /* Fallback environment variable name */
+ char *compiled; /* Fallback compiled in default value */
+ char *val; /* Option's value */
+ char *label; /* Label for field in connect dialog */
+ char *dispchar; /* Character to display for this field
+ in a connect dialog. Values are:
+ "" Display entered value as is
+ "*" Password field - hide value
+ "D" Debug options - don't
+ create a field by default */
+ int dispsize; /* Field size in characters for dialog */
+ };
</synopsis>
Returns the address of the connection options structure. This may
Returns the result status of the query. PQresultStatus can return one of the following values:
<synopsis>
PGRES_EMPTY_QUERY,
-PGRES_COMMAND_OK, /* the query was a command returning no data */
-PGRES_TUPLES_OK, /* the query successfully returned tuples */
-PGRES_COPY_OUT, /* Copy Out (from server) data transfer started */
-PGRES_COPY_IN, /* Copy In (to server) data transfer started */
-PGRES_BAD_RESPONSE, /* an unexpected response was received */
+PGRES_COMMAND_OK, /* the query was a command returning no data */
+PGRES_TUPLES_OK, /* the query successfully returned tuples */
+PGRES_COPY_OUT, /* Copy Out (from server) data transfer started */
+PGRES_COPY_IN, /* Copy In (to server) data transfer started */
+PGRES_BAD_RESPONSE, /* an unexpected response was received */
PGRES_NONFATAL_ERROR,
PGRES_FATAL_ERROR
</synopsis>
If the result status is PGRES_TUPLES_OK, then the
routines described below can be used to retrieve the
tuples returned by the query. Note that a SELECT that
- happens to retrieve zero tuples still shows PGRES_TUPLES_OK;
+ happens to retrieve zero tuples still shows PGRES_TUPLES_OK.
PGRES_COMMAND_OK is for commands that can never return tuples.
</Para>
</ListItem>
<Para>
<Function>PQfsize</Function>
Returns the size in bytes of the field
- associated with the given field index. If the size
- returned is -1, the field is a variable length
- field. Field indices start at 0.
+ associated with the given field index.
+ Field indices start at 0.
<synopsis>
int PQfsize(PGresult *res,
int field_index);
</synopsis>
+ PQfsize returns the space allocated for this field in a database
+ tuple, in other words the size of the server's binary representation
+ of the data type. -1 is returned if the field is variable size.
</Para>
</ListItem>
</synopsis>
For most queries, the value returned by PQgetvalue
is a null-terminated ASCII string representation
- of the attribute value. If the query extracted data from
- a <Acronym>BINARY</Acronym> cursor, then the value returned by
+ of the attribute value. But if PQbinaryTuples() is TRUE,
+ the value returned by
PQgetvalue is the binary representation of the
- type in the internal format of the backend server.
- It is the programmer's responsibility to cast and
+ type in the internal format of the backend server
+ (but not including the size word, if the field is variable-length).
+ It is then the programmer's responsibility to cast and
convert the data to the correct C type. The pointer
returned by PQgetvalue points to storage that is
part of the PGresult structure. One should not modify it,
<ListItem>
<Para>
-<Function>PQgetisnull</Function>
- Tests a field for a NULL entry.
- Tuple and field indices start at 0.
+<Function>PQgetlength</Function>
+ Returns the length of a field (attribute) in bytes.
+ Tuple and field indices start at 0.
<synopsis>
-int PQgetisnull(PGresult *res,
+int PQgetlength(PGresult *res,
int tup_num,
int field_num);
</synopsis>
- This function returns 1 if the field contains a NULL, 0 if
- it contains a non-null value. (Note that PQgetvalue
- will return an empty string, not a null pointer, for a NULL
- field.)
+This is the actual data length for the particular data value, that is the
+size of the object pointed to by PQgetvalue. Note that for ASCII-represented
+values, this size has little to do with the binary size reported by PQfsize.
</Para>
</ListItem>
<ListItem>
<Para>
-<Function>PQgetlength</Function>
- Returns the length of a field
- (attribute) in bytes.
- Tuple and field indices start at 0.
+<Function>PQgetisnull</Function>
+ Tests a field for a NULL entry.
+ Tuple and field indices start at 0.
<synopsis>
-int PQgetlength(PGresult *res,
+int PQgetisnull(PGresult *res,
int tup_num,
int field_num);
</synopsis>
-This is the actual data length for the particular data value,
-whereas PQfsize shows the allocated space for all entries in
-this column.
-If the field is a struct
- varlena, the length returned here does not include
- the size field of the varlena, i.e., it is 4 bytes
- less.
+ This function returns 1 if the field contains a NULL, 0 if
+ it contains a non-null value. (Note that PQgetvalue
+ will return an empty string, not a null pointer, for a NULL
+ field.)
</Para>
</ListItem>
PQprintOpt* po);
struct _PQprintOpt
- {
- pqbool header; /* print output field headings and row count */
- pqbool align; /* fill align the fields */
- pqbool standard; /* old brain dead format */
- pqbool html3; /* output html tables */
- pqbool expanded; /* expand tables */
- pqbool pager; /* use pager for output if needed */
- char *fieldSep; /* field separator */
- char *tableOpt; /* insert to HTML <table ...> */
- char *caption; /* HTML <caption> */
- char **fieldName; /* null terminated array of replacement field names */
- };
+ {
+ pqbool header; /* print output field headings and row count */
+ pqbool align; /* fill align the fields */
+ pqbool standard; /* old brain dead format */
+ pqbool html3; /* output html tables */
+ pqbool expanded; /* expand tables */
+ pqbool pager; /* use pager for output if needed */
+ char *fieldSep; /* field separator */
+ char *tableOpt; /* insert to HTML <table ...> */
+ char *caption; /* HTML <caption> */
+ char **fieldName; /* null terminated array of replacement field names */
+ };
</synopsis>
This function is intended to replace PQprintTuples(), which is
now obsolete. The <FileName>psql</FileName> program uses
the application may check PQisBusy and/or PQnotifies to see if their state
has changed.
PQconsumeInput may be called even if the application is not
- prepared to deal with a result or notification just yet.
- It will read available data and save it in a buffer, thereby
+ prepared to deal with a result or notification just yet. The
+ routine will read available data and save it in a buffer, thereby
causing a select(2) read-ready indication to go away. The
application can thus use PQconsumeInput to clear the select
condition immediately, and then examine the results at leisure.
<Title>Fast Path</Title>
<Para>
+<ProductName>Postgres</ProductName> provides a fast path interface to send
+function calls to the backend. This is a trapdoor into system internals and
+can be a potential security hole. Most users will not need this feature.
+
+<Para>
<ItemizedList>
<ListItem>
<Para>
-<ProductName>Postgres</ProductName> provides a fast path interface to send function
- calls to the backend. This is a trapdoor into
- system internals and can be a potential security hole.
- Most users will not need this feature.
+<Function>PQfn</Function>
+ Request execution of a backend function via the fast path interface.
<synopsis>
PGresult* PQfn(PGconn* conn,
int fnid,
executed.
result_buf is the buffer in which
to place the return value. The caller must have allocated
- sufficient space to store the return value. The
- result length will be returned in the storage pointed
- to by result_len. If the result is to be an integer
- value, than result_is_int should be set to 1; otherwise
- it should be set to 0. args and nargs specify the
- arguments to the function.
+ sufficient space to store the return value (there is no check!).
+ The actual result length will be returned in the integer pointed
+ to by result_len. If a 4-byte integer result is expected, set
+ result_is_int to 1; otherwise set it to 0. (Setting result_is_int to 1
+ tells libpq to byte-swap the value if necessary, so that it is
+ delivered as a proper int value for the client machine. When
+ result_is_int is 0, the byte string sent by the backend is returned
+ unmodified.)
+ args and nargs specify the arguments to be passed to the function.
<synopsis>
typedef struct {
int len;
removed from the list of notifications.
<synopsis>
PGnotify* PQnotifies(PGconn *conn);
+
+typedef struct pgNotify
+ {
+ char relname[NAMEDATALEN]; /* name of relation
+ * containing data */
+ int be_pid; /* process id of backend */
+ } PGnotify;
</synopsis>
After processing a PGnotify object returned by PQnotifies,
be sure to free it with free() to avoid a memory leak.
+ NOTE: in <productname>Postgres</productname> 6.4 and later,
+ the be_pid is the notifying backend's, whereas in earlier versions
+ it was always your own backend's PID.
</Para>
</ListItem>
</ItemizedList>
<Para>
To use a special notice processor, call <function>PQsetNoticeProcessor</function> just after
-any creation of a new PGconn object.
+creation of a new PGconn object.
</Sect1>
*/
if (PQstatus(conn) == CONNECTION_BAD)
{
- fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
- fprintf(stderr, "%s", PQerrorMessage(conn));
+ fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
+ fprintf(stderr, "%s", PQerrorMessage(conn));
exit_nicely(conn);
}
/* first, print out the attribute names */
nFields = PQnfields(res);
for (i = 0; i < nFields; i++)
- printf("%-15s", PQfname(res, i));
+ printf("%-15s", PQfname(res, i));
printf("\n\n");
/* next, print out the instances */
for (i = 0; i < PQntuples(res); i++)
{
for (j = 0; j < nFields; j++)
- printf("%-15s", PQgetvalue(res, i, j));
+ printf("%-15s", PQgetvalue(res, i, j));
printf("\n");
}
*/
if (PQstatus(conn) == CONNECTION_BAD)
{
- fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
- fprintf(stderr, "%s", PQerrorMessage(conn));
+ fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
+ fprintf(stderr, "%s", PQerrorMessage(conn));
exit_nicely(conn);
}
while ((notify = PQnotifies(conn)) != NULL)
{
fprintf(stderr,
- "ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
+ "ASYNC NOTIFY of '%s' from backend pid '%d' received\n",
notify->relname, notify->be_pid);
free(notify);
}
*/
if (PQstatus(conn) == CONNECTION_BAD)
{
- fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
- fprintf(stderr, "%s", PQerrorMessage(conn));
+ fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
+ fprintf(stderr, "%s", PQerrorMessage(conn));
exit_nicely(conn);
}
for (i = 0; i < 3; i++)
{
- printf("type[%d] = %d, size[%d] = %d\n",
+ printf("type[%d] = %d, size[%d] = %d\n",
i, PQftype(res, i),
i, PQfsize(res, i));
}
*/
pval = (POLYGON *) malloc(plen + VARHDRSZ);
pval->size = plen;
- memmove((char *) &pval->npts, PQgetvalue(res, i, p_fnum), plen);
- printf("tuple %d: got\n", i);
- printf(" i = (%d bytes) %d,\n",
+ memmove((char *) &pval->npts, PQgetvalue(res, i, p_fnum), plen);
+ printf("tuple %d: got\n", i);
+ printf(" i = (%d bytes) %d,\n",
PQgetlength(res, i, i_fnum), *ival);
- printf(" d = (%d bytes) %f,\n",
+ printf(" d = (%d bytes) %f,\n",
PQgetlength(res, i, d_fnum), *dval);
- printf(" p = (%d bytes) %d points \tboundbox = (hi=%f/%f, lo = %f,%f)\n",
+ printf(" p = (%d bytes) %d points \tboundbox = (hi=%f/%f, lo = %f,%f)\n",
PQgetlength(res, i, d_fnum),
pval->npts,
pval->boundbox.xh,
*/
fd = open(filename, O_RDONLY, 0666);
if (fd < 0) { /* error */
- fprintf(stderr, "can't open unix file
+ fprintf(stderr, "can't open unix file %s\n", filename);
}
/*
*/
lobjId = lo_creat(conn, INV_READ|INV_WRITE);
if (lobjId == 0) {
- fprintf(stderr, "can't create large object");
+ fprintf(stderr, "can't create large object\n");
}
lobj_fd = lo_open(conn, lobjId, INV_WRITE);
while ((nbytes = read(fd, buf, BUFSIZE)) > 0) {
tmp = lo_write(conn, lobj_fd, buf, nbytes);
if (tmp < nbytes) {
- fprintf(stderr, "error while reading
+ fprintf(stderr, "error while reading large object\n");
}
}
lobj_fd = lo_open(conn, lobjId, INV_READ);
if (lobj_fd < 0) {
- fprintf(stderr,"can't open large object %d",
+ fprintf(stderr,"can't open large object %d\n",
lobjId);
}
fprintf(stderr,">>> %s", buf);
nread += nbytes;
}
- fprintf(stderr,"0);
+ fprintf(stderr,"\n");
lo_close(conn, lobj_fd);
}
lobj_fd = lo_open(conn, lobjId, INV_READ);
if (lobj_fd < 0) {
- fprintf(stderr,"can't open large object %d",
+ fprintf(stderr,"can't open large object %d\n",
lobjId);
}
nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
nwritten += nbytes;
}
- fprintf(stderr,"0);
+ fprintf(stderr,"\n");
lo_close(conn, lobj_fd);
}
*/
lobj_fd = lo_open(conn, lobjId, INV_READ);
if (lobj_fd < 0) {
- fprintf(stderr,"can't open large object %d",
+ fprintf(stderr,"can't open large object %d\n",
lobjId);
}
*/
fd = open(filename, O_CREAT|O_WRONLY, 0666);
if (fd < 0) { /* error */
- fprintf(stderr, "can't open unix file
+ fprintf(stderr, "can't open unix file %s\n",
filename);
}
while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0) {
tmp = write(fd, buf, nbytes);
if (tmp < nbytes) {
- fprintf(stderr,"error while writing
+ fprintf(stderr,"error while writing %s\n",
filename);
}
}
PGresult *res;
if (argc != 4) {
- fprintf(stderr, "Usage: %s database_name in_filename out_filename0,
+ fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
argv[0]);
exit(1);
}
/* check to see that the backend connection was successfully made */
if (PQstatus(conn) == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '%s' failed.0, database);
+ fprintf(stderr,"Connection to database '%s' failed.\n", database);
fprintf(stderr,"%s",PQerrorMessage(conn));
exit_nicely(conn);
}
res = PQexec(conn, "begin");
PQclear(res);
- printf("importing file
+ printf("importing file %s\n", in_filename);
/* lobjOid = importFile(conn, in_filename); */
lobjOid = lo_import(conn, in_filename);
/*
- printf("as large object %d.0, lobjOid);
+ printf("as large object %d.\n", lobjOid);
- printf("picking out bytes 1000-2000 of the large object0);
+ 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's0);
+ printf("overwriting bytes 1000-2000 of the large object with X's\n");
overwrite(conn, lobjOid, 1000, 1000);
*/
- printf("exporting large object to file
+ printf("exporting large object to file %s\n", out_filename);
/* exportFile(conn, lobjOid, out_filename); */
lo_export(conn, lobjOid,out_filename);
</Term>
<ListItem>
<Para>
-
A bit map with one bit for each field in the row. The 1st
- field corresponds to bit 7 of the 1st byte, the 2nd field
- corresponds to bit 6 of the 1st byte, the 8th field corresponds
- to bit 0 of the 1st byte, the 9th field corresponds to bit 8 of
- the 2nd byte, and so on. The bit is set if the value of the
- corresponding field is not NULL.
+ field corresponds to bit 7 (MSB) of the 1st byte, the 2nd
+ field corresponds to bit 6 of the 1st byte, the 8th field
+ corresponds to bit 0 (LSB) of the 1st byte, the 9th field
+ corresponds to bit 7 of the 2nd byte, and so on. Each bit
+ is set if the value of the corresponding field is not NULL.
+ If the number of fields is not a multiple of 8, the remainder
+ of the last byte in the bit map is wasted.
</Para>
<Para>
Then, for each field with a non-NULL value, there is the following:
<ListItem>
<Para>
Specifies the value of the field itself in <Acronym>ASCII</Acronym>
- characters. <Replaceable>n</Replaceable> is the above size minus 4.
+ characters. <Replaceable>n</Replaceable> is the above
+ size minus 4.
+ There is no trailing '\0' in the field data; the front
+ end must add one if it wants one.
</Para>
</ListItem>
</VarListEntry>
<ListItem>
<Para>
A bit map with one bit for each field in the row. The 1st
- field corresponds to bit 7 of the 1st byte, the 2nd field
- corresponds to bit 6 of the 1st byte, the 8th field corresponds
- to bit 0 of the 1st byte, the 9th field corresponds to bit 8 of
- the 2nd byte, and so on. The bit is set if the value of the
- corresponding field is not NULL.
+ field corresponds to bit 7 (MSB) of the 1st byte, the 2nd
+ field corresponds to bit 6 of the 1st byte, the 8th field
+ corresponds to bit 0 (LSB) of the 1st byte, the 9th field
+ corresponds to bit 7 of the 2nd byte, and so on. Each bit
+ is set if the value of the corresponding field is not NULL.
+ If the number of fields is not a multiple of 8, the remainder
+ of the last byte in the bit map is wasted.
</Para>
<Para>
Then, for each field with a non-NULL value, there is the following:
</Term>
<ListItem>
<Para>
- The process ID of the backend process.
+ The process ID of the notifying backend process.
</Para>
</ListItem>
</VarListEntry>
</Term>
<ListItem>
<Para>
- The name of the relation that the notify has been raised on.
+ The name of the condition that the notify has been raised on.
</Para>
</ListItem>
</VarListEntry>
</Term>
<ListItem>
<Para>
- Specifies the number of fields in a row (and may be zero).
+ Specifies the number of fields in a row (may be zero).
</Para>
<Para>
Then, for each field, there is the following:
</Term>
<ListItem>
<Para>
- The database name, defaults to the user name if omitted.
+ The database name, defaults to the user name if empty.
</Para>
</ListItem>
</VarListEntry>