aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/libpq/fe-exec.c1386
1 files changed, 714 insertions, 672 deletions
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index c5668637f5f..9e5079a4b13 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.19 1996/11/20 22:35:19 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.20 1996/12/13 09:25:08 bryanh Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,7 +32,7 @@ struct winsize {
} screen_size;
#endif
-/* the tuples array in a PGresGroup has to grow to accommodate the tuples */
+/* the rows array in a PGresGroup has to grow to accommodate the rows */
/* returned. Each time, we grow by this much: */
#define TUPARR_GROW_BY 100
@@ -64,25 +64,25 @@ PQclear(PGresult* res)
int i,j;
if (!res)
- return;
+ return;
- /* free all the tuples */
+ /* free all the rows */
for (i=0;i<res->ntups;i++) {
- for (j=0;j<res->numAttributes;j++) {
- if (res->tuples[i][j].value)
- free(res->tuples[i][j].value);
- }
- free(res->tuples[i]);
+ for (j=0;j<res->numAttributes;j++) {
+ if (res->tuples[i][j].value)
+ free(res->tuples[i][j].value);
+ }
+ free(res->tuples[i]);
}
free(res->tuples);
/* free all the attributes */
for (i=0;i<res->numAttributes;i++) {
- if (res->attDescs[i].name)
- free(res->attDescs[i].name);
+ if (res->attDescs[i].name)
+ free(res->attDescs[i].name);
}
free(res->attDescs);
-
+
/* free the structure itself */
free(res);
}
@@ -114,7 +114,7 @@ makeEmptyPGresult(PGconn *conn, ExecStatusType status)
/*
* getTuple -
- * get the next tuple from the stream
+ * get the next row from the stream
*
* the CALLER is responsible from freeing the PGresAttValue returned
*/
@@ -127,9 +127,9 @@ getTuple(PGconn *conn, PGresult* result, int binary)
int bitmap_index = 0;
int i;
int nbytes; /* the number of bytes in bitmap */
- char bmap; /* One byte of the bitmap */
- int bitcnt = 0; /* number of bits examined in current byte */
- int vlen; /* length of the current field value */
+ char bmap; /* One byte of the bitmap */
+ int bitcnt = 0; /* number of bits examined in current byte */
+ int vlen; /* length of the current field value */
FILE *pfin = conn->Pfin;
FILE *pfdebug = conn->Pfdebug;
@@ -147,7 +147,7 @@ getTuple(PGconn *conn, PGresult* result, int binary)
if (pqGetnchar(bitmap, nbytes, pfin, pfdebug) == 1){
sprintf(conn->errorMessage,
- "Error reading null-values bitmap from tuple data stream\n");
+ "Error reading null-values bitmap from row data stream\n");
return NULL;
}
@@ -155,24 +155,24 @@ getTuple(PGconn *conn, PGresult* result, int binary)
for (i=0;i<nfields;i++) {
if (!(bmap & 0200)) {
- /* if the field value is absent, make it '\0' */
- tup[i].value = (char*)malloc(1);
- tup[i].value[0] = '\0';
- tup[i].len = NULL_LEN;
+ /* if the field value is absent, make it '\0' */
+ tup[i].value = (char*)malloc(1);
+ tup[i].value[0] = '\0';
+ tup[i].len = NULL_LEN;
}
else {
/* get the value length (the first four bytes are for length) */
pqGetInt(&vlen, VARHDRSZ, pfin, pfdebug);
if (binary == 0) {
- vlen = vlen - VARHDRSZ;
- }
+ vlen = vlen - VARHDRSZ;
+ }
if (vlen < 0)
- vlen = 0;
+ vlen = 0;
tup[i].len = vlen;
tup[i].value = (char*) malloc(vlen + 1);
/* read in the value; */
if (vlen > 0)
- pqGetnchar((char*)(tup[i].value), vlen, pfin, pfdebug);
+ pqGetnchar((char*)(tup[i].value), vlen, pfin, pfdebug);
tup[i].value[vlen] = '\0';
}
/* get the appropriate bitmap */
@@ -191,7 +191,7 @@ getTuple(PGconn *conn, PGresult* result, int binary)
/*
* addTuple
- * add a tuple to the PGresult structure, growing it if necessary
+ * add a row to the PGresult structure, growing it if necessary
* to accommodate
*
*/
@@ -204,11 +204,11 @@ addTuple(PGresult* res, PGresAttValue* tup)
if (res->ntups == 0)
res->tuples = (PGresAttValue**)
- malloc(res->tupArrSize * sizeof(PGresAttValue*));
+ malloc(res->tupArrSize * sizeof(PGresAttValue*));
else
/* we can use realloc because shallow copying of the structure is okay */
res->tuples = (PGresAttValue**)
- realloc(res->tuples, res->tupArrSize * sizeof(PGresAttValue*));
+ realloc(res->tuples, res->tupArrSize * sizeof(PGresAttValue*));
}
res->tuples[res->ntups] = tup;
@@ -217,11 +217,11 @@ addTuple(PGresult* res, PGresAttValue* tup)
/*
* PGresult
- * fill out the PGresult structure with result tuples from the backend
+ * fill out the PGresult structure with result rows from the backend
* this is called after query has been successfully run and we have
* a portal name
*
- * ASSUMPTION: we assume only *1* tuple group is returned from the backend
+ * ASSUMPTION: we assume only *1* row group is returned from the backend
*
* the CALLER is reponsible for free'ing the new PGresult allocated here
*
@@ -249,7 +249,7 @@ makePGresult(PGconn* conn, char* pname)
/* the next two bytes are the number of fields */
if (pqGetInt(&nfields, 2, pfin, pfdebug) == 1) {
sprintf(conn->errorMessage,
- "could not get the number of fields from the 'T' message\n");
+ "could not get the number of fields from the 'T' message\n");
goto makePGresult_badResponse_return;
}
else
@@ -267,10 +267,10 @@ makePGresult(PGconn* conn, char* pname)
int adtsize;
if ( pqGets(typName, MAX_MESSAGE_LEN, pfin, pfdebug) ||
- pqGetInt(&adtid, 4, pfin, pfdebug) ||
- pqGetInt(&adtsize, 2, pfin, pfdebug)) {
+ pqGetInt(&adtid, 4, pfin, pfdebug) ||
+ pqGetInt(&adtsize, 2, pfin, pfdebug)) {
sprintf(conn->errorMessage,
- "error reading type information from the 'T' message\n");
+ "error reading type information from the 'T' message\n");
goto makePGresult_badResponse_return;
}
result->attDescs[i].name = malloc(strlen(typName)+1);
@@ -284,50 +284,49 @@ makePGresult(PGconn* conn, char* pname)
/* process the data stream until we're finished */
while(!done) {
switch (id) {
- case 'T': /* a new tuple group */
+ case 'T': /* a new row group */
sprintf(conn->errorMessage,
- "makePGresult() -- is not equipped to handle multiple tuple groups.\n");
+ "makePGresult() -- "
+ "is not equipped to handle multiple row groups.\n");
goto makePGresult_badResponse_return;
- case 'B': /* a tuple in binary format */
- case 'D': /* a tuple in ASCII format */
+ case 'B': /* a row in binary format */
+ case 'D': /* a row in ASCII format */
newTup = getTuple(conn, result, (id == 'B'));
if (newTup == NULL)
- goto makePGresult_badResponse_return;
+ goto makePGresult_badResponse_return;
addTuple(result,newTup);
break;
-/* case 'A':
- sprintf(conn->errorMessage, "Asynchronous portals not supported");
- result->resultStatus = PGRES_NONFATAL_ERROR;
- return result;
- break;
-*/
- case 'C': /* end of portal tuple stream */
+ case 'C': /* end of portal row stream */
{
char command[MAX_MESSAGE_LEN];
- pqGets(command,MAX_MESSAGE_LEN, pfin, pfdebug); /* read the command tag */
+ pqGets(command,MAX_MESSAGE_LEN, pfin, pfdebug); /* read command tag */
done = 1;
}
break;
case 'E': /* errors */
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) {
- sprintf(conn->errorMessage,
- "Error return detected from backend, but error message cannot be read");
+ sprintf(conn->errorMessage,
+ "Error return detected from backend, "
+ "but error message cannot be read");
}
result->resultStatus = PGRES_FATAL_ERROR;
return result;
break;
case 'N': /* notices from the backend */
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) {
- sprintf(conn->errorMessage,
- "Notice return detected from backend, but error message cannot be read");
- } else
- /* XXXX send Notices to stderr for now */
- fprintf(stderr, "%s\n", conn->errorMessage);
+ sprintf(conn->errorMessage,
+ "Notice return detected from backend, "
+ "but error message cannot be read");
+ } else
+ /* XXXX send Notices to stderr for now */
+ fprintf(stderr, "%s\n", conn->errorMessage);
break;
default: /* uh-oh
- this should never happen but frequently does when the
- backend dumps core */
- sprintf(conn->errorMessage,"FATAL: unexpected results from the backend, it probably dumped core.");
+ this should never happen but frequently does when the
+ backend dumps core */
+ sprintf(conn->errorMessage,
+ "FATAL: unrecognized data from the backend. "
+ "It probably dumped core.");
fprintf(stderr, conn->errorMessage);
result->resultStatus = PGRES_FATAL_ERROR;
return result;
@@ -371,7 +370,7 @@ PQexec(PGconn* conn, const char* query)
FILE *pfin, *pfout, *pfdebug;
#ifdef PQ_NOTIFY_PATCH
- int isCommand = 0; /* DZ - 31-8-1996 */
+ int isCommand = 0; /* DZ - 31-8-1996 */
#endif
pname[0]='\0';
@@ -409,9 +408,9 @@ PQexec(PGconn* conn, const char* query)
/* send the query to the backend; */
if (pqPuts(buffer,pfout, pfdebug) == 1) {
(void) sprintf(conn->errorMessage,
- "PQexec() -- while sending query: %s\n"
+ "PQexec() -- while sending query: %s\n"
"-- fprintf to Pfout failed: errno=%d\n%s\n",
- query, errno,strerror(errno));
+ query, errno,strerror(errno));
return NULL;
}
@@ -427,7 +426,7 @@ PQexec(PGconn* conn, const char* query)
if (id == EOF) {
/* hmm, no response from the backend-end, that's bad */
(void) sprintf(conn->errorMessage,
- "PQexec() -- Request was sent to backend, but backend "
+ "PQexec() -- Request was sent to backend, but backend "
"closed the channel before "
"responding. This probably means the backend "
"terminated abnormally before or while processing "
@@ -438,30 +437,31 @@ PQexec(PGconn* conn, const char* query)
switch (id) {
case 'A':
- newNotify = (PGnotify*)malloc(sizeof(PGnotify));
- pqGetInt(&(newNotify->be_pid), 4, pfin, pfdebug);
- pqGets(newNotify->relname, NAMEDATALEN, pfin, pfdebug);
- DLAddTail(conn->notifyList, DLNewElem(newNotify));
- /* async messages are piggy'ed back on other messages,
- so we stay in the while loop for other messages */
- break;
- case 'C': /* portal query command, no tuples returned */
+ newNotify = (PGnotify*)malloc(sizeof(PGnotify));
+ pqGetInt(&(newNotify->be_pid), 4, pfin, pfdebug);
+ pqGets(newNotify->relname, NAMEDATALEN, pfin, pfdebug);
+ DLAddTail(conn->notifyList, DLNewElem(newNotify));
+ /* async messages are piggy'ed back on other messages,
+ so we stay in the while loop for other messages */
+ break;
+ case 'C': /* portal query command, no rows returned */
if (pqGets(cmdStatus, MAX_MESSAGE_LEN, pfin, pfdebug) == 1) {
- sprintf(conn->errorMessage,
- "PQexec() -- query command completed, but return message from backend cannot be read");
- return (PGresult*)NULL;
+ sprintf(conn->errorMessage,
+ "PQexec() -- query command completed, "
+ "but return message from backend cannot be read.");
+ return (PGresult*)NULL;
}
else {
- /*
- // since backend may produce more than one result for some commands
- // need to poll until clear
- // send an empty query down, and keep reading out of the pipe
- // until an 'I' is received.
- */
- clear = 0;
- error = 0;
-
- pqPuts("Q ",pfout,pfdebug); /* send an empty query */
+ /*
+ // since backend may produce more than one result for some commands
+ // need to poll until clear
+ // send an empty query down, and keep reading out of the pipe
+ // until an 'I' is received.
+ */
+ clear = 0;
+ error = 0;
+
+ pqPuts("Q ",pfout,pfdebug); /* send an empty query */
#ifdef PQ_NOTIFY_PATCH
/*
* Set a flag and process messages in the usual way because
@@ -469,71 +469,71 @@ PQexec(PGconn* conn, const char* query)
*/
isCommand = 1;
#else
- while (!clear)
- {
- if (pqGets(buffer,ERROR_MSG_LENGTH,pfin,pfdebug) == 1)
- clear = 1;
- /*
- // Rules can create error messages while we are waiting
- // for the 'I'.
- */
- if (buffer[0] == 'E') {
- strcpy(conn->errorMessage, &buffer[1]);
- error++;
- }
- clear = (buffer[0] == 'I');
- }
- if (error) {
- return (PGresult*)NULL;
- }
- result = makeEmptyPGresult(conn,PGRES_COMMAND_OK);
- strncpy(result->cmdStatus,cmdStatus, CMDSTATUS_LEN-1);
- return result;
+ while (!clear)
+ {
+ if (pqGets(buffer,ERROR_MSG_LENGTH,pfin,pfdebug) == 1)
+ clear = 1;
+ /*
+ // Rules can create error messages while we are waiting
+ // for the 'I'.
+ */
+ if (buffer[0] == 'E') {
+ strcpy(conn->errorMessage, &buffer[1]);
+ error++;
+ }
+ clear = (buffer[0] == 'I');
+ }
+ if (error) {
+ return (PGresult*)NULL;
+ }
+ result = makeEmptyPGresult(conn,PGRES_COMMAND_OK);
+ strncpy(result->cmdStatus,cmdStatus, CMDSTATUS_LEN-1);
+ return result;
#endif
}
break;
case 'E': /* error return */
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) {
- (void) sprintf(conn->errorMessage,
- "PQexec() -- error return detected from backend, but error message cannot be read");
+ (void) sprintf(conn->errorMessage,
+ "PQexec() -- error return detected from backend, "
+ "but attempt to read the error message failed.");
}
return (PGresult*)NULL;
break;
case 'I': /* empty query */
/* read the throw away the closing '\0' */
{
- int c;
- if ((c = pqGetc(pfin,pfdebug)) != '\0') {
- fprintf(stderr,"error!, unexpected character %c following 'I'\n", c);
- }
-#ifdef PQ_NOTIFY_PATCH
- if (isCommand) {
- /*
- * If this is the result of a portal query command set the
- * command status and message accordingly. DZ - 31-8-1996
- */
- result = makeEmptyPGresult(conn,PGRES_COMMAND_OK);
- strncpy(result->cmdStatus,cmdStatus, CMDSTATUS_LEN-1);
- return result;
- }
-#endif
- result = makeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
- return result;
+ int c;
+ if ((c = pqGetc(pfin,pfdebug)) != '\0') {
+ fprintf(stderr,"error!, unexpected character %c following 'I'\n", c);
+ }
+ if (isCommand) {
+ /*
+ * If this is the result of a portal query command set the
+ * command status and message accordingly. DZ - 31-8-1996
+ */
+ result = makeEmptyPGresult(conn,PGRES_COMMAND_OK);
+ strncpy(result->cmdStatus,cmdStatus, CMDSTATUS_LEN-1);
+ return result;
+ }
+ result = makeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
+ return result;
}
break;
case 'N': /* notices from the backend */
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) {
- sprintf(conn->errorMessage,
- "PQexec() -- error return detected from backend, but error message cannot be read");
- return (PGresult*)NULL;
+ sprintf(conn->errorMessage,
+ "PQexec() -- Notice detected from backend, "
+ "but attempt to read the notice failed.");
+ return (PGresult*)NULL;
}
else
- fprintf(stderr,"%s", conn->errorMessage);
+ fprintf(stderr,"%s", conn->errorMessage);
break;
case 'P': /* synchronous (normal) portal */
- pqGets(pname,MAX_MESSAGE_LEN,pfin, pfdebug); /* read in the portal name*/
+ pqGets(pname,MAX_MESSAGE_LEN,pfin, pfdebug); /* read in portal name*/
break;
- case 'T': /* actual tuple results: */
+ case 'T': /* actual row results: */
return makePGresult(conn, pname);
break;
case 'D': /* copy command began successfully */
@@ -544,8 +544,8 @@ PQexec(PGconn* conn, const char* query)
break;
default:
sprintf(conn->errorMessage,
- "unknown protocol character %c read from backend\n",
- id);
+ "unknown protocol character %c read from backend\n",
+ id);
return (PGresult*)NULL;
} /* switch */
} /* while (1)*/
@@ -571,13 +571,13 @@ PQnotifies(PGconn *conn)
if (!conn) return NULL;
if (conn->status != CONNECTION_OK)
- return NULL;
+ return NULL;
/* RemHead returns NULL if list is empy */
e = DLRemHead(conn->notifyList);
if (e)
- return (PGnotify*)DLE_VAL(e);
+ return (PGnotify*)DLE_VAL(e);
else
- return NULL;
+ return NULL;
}
/*
@@ -590,12 +590,12 @@ PQnotifies(PGconn *conn)
* the terminating \n (like gets(3)).
*
* RETURNS:
- * EOF if it is detected or invalid arguments are given
- * 0 if EOL is reached (i.e., \n has been read)
- * (this is required for backward-compatibility -- this
- * routine used to always return EOF or 0, assuming that
- * the line ended within maxlen bytes.)
- * 1 in other cases
+ * EOF if it is detected or invalid arguments are given
+ * 0 if EOL is reached (i.e., \n has been read)
+ * (this is required for backward-compatibility -- this
+ * routine used to always return EOF or 0, assuming that
+ * the line ended within maxlen bytes.)
+ * 1 in other cases
*/
int
PQgetline(PGconn *conn, char *s, int maxlen)
@@ -605,22 +605,22 @@ PQgetline(PGconn *conn, char *s, int maxlen)
if (!conn) return EOF;
if (!conn->Pfin || !s || maxlen <= 1)
- return(EOF);
+ return(EOF);
for (; maxlen > 1 &&
- (c = pqGetc(conn->Pfin, conn->Pfdebug)) != '\n' &&
- c != EOF;
- --maxlen) {
- *s++ = c;
+ (c = pqGetc(conn->Pfin, conn->Pfdebug)) != '\n' &&
+ c != EOF;
+ --maxlen) {
+ *s++ = c;
}
*s = '\0';
if (c == EOF) {
- return(EOF); /* error -- reached EOF before \n */
+ return(EOF); /* error -- reached EOF before \n */
} else if (c == '\n') {
- return(0); /* done with this line */
+ return(0); /* done with this line */
}
- return(1); /* returning a full buffer */
+ return(1); /* returning a full buffer */
}
@@ -634,19 +634,19 @@ void
PQputline(PGconn *conn, const char *s)
{
if (conn && (conn->Pfout)) {
- (void) fputs(s, conn->Pfout);
- fflush(conn->Pfout);
+ (void) fputs(s, conn->Pfout);
+ fflush(conn->Pfout);
}
}
/*
* PQendcopy
- * called while waiting for the backend to respond with success/failure
- * to a "copy".
+ * called while waiting for the backend to respond with success/failure
+ * to a "copy".
*
* RETURNS:
- * 0 on failure
- * 1 on success
+ * 0 on failure
+ * 1 on success
*/
int
PQendcopy(PGconn *conn)
@@ -660,26 +660,27 @@ PQendcopy(PGconn *conn)
pfdebug = conn->Pfdebug;
if ( (id = pqGetc(pfin,pfdebug)) > 0)
- return(0);
+ return(0);
switch (id) {
case 'Z': /* backend finished the copy */
- return(1);
+ return(1);
case 'E':
case 'N':
- if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) {
- sprintf(conn->errorMessage,
- "Error return detected from backend, but error message cannot be read");
- }
- return(0);
- break;
+ if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) {
+ sprintf(conn->errorMessage,
+ "Error return detected from backend, "
+ "but attempt to read the message failed.");
+ }
+ return(0);
+ break;
default:
- (void) sprintf(conn->errorMessage,
- "FATAL: PQendcopy: protocol error: id=%x\n",
- id);
- fputs(conn->errorMessage, stderr);
- fprintf(stderr,"resetting connection\n");
- PQreset(conn);
- return(0);
+ (void) sprintf(conn->errorMessage,
+ "FATAL: PQendcopy: protocol error: id=%x\n",
+ id);
+ fputs(conn->errorMessage, stderr);
+ fprintf(stderr,"resetting connection\n");
+ PQreset(conn);
+ return(0);
}
}
@@ -706,12 +707,12 @@ fill (int length, int max, char filler, FILE *fp)
*/
void
PQdisplayTuples(PGresult *res,
- FILE *fp, /* where to send the output */
- int fillAlign, /* pad the fields with spaces */
- const char *fieldSep, /* field separator */
- int printHeader, /* display headers? */
- int quiet
- )
+ FILE *fp, /* where to send the output */
+ int fillAlign, /* pad the fields with spaces */
+ const char *fieldSep, /* field separator */
+ int printHeader, /* display headers? */
+ int quiet
+ )
{
#define DEFAULT_FIELD_SEP " "
@@ -721,14 +722,14 @@ PQdisplayTuples(PGresult *res,
int fLength[MAX_FIELDS];
if (fieldSep == NULL)
- fieldSep = DEFAULT_FIELD_SEP;
+ fieldSep = DEFAULT_FIELD_SEP;
/* Get some useful info about the results */
nFields = PQnfields(res);
nTuples = PQntuples(res);
if (fp == NULL)
- fp = stdout;
+ fp = stdout;
/* Zero the initial field lengths */
for (j=0 ; j < nFields; j++) {
@@ -737,47 +738,47 @@ PQdisplayTuples(PGresult *res,
/* Find the max length of each field in the result */
/* will be somewhat time consuming for very large results */
if (fillAlign) {
- for (i=0; i < nTuples; i++) {
- for (j=0 ; j < nFields; j++) {
- if (PQgetlength(res,i,j) > fLength[j])
- fLength[j] = PQgetlength(res,i,j);
- }
- }
+ for (i=0; i < nTuples; i++) {
+ for (j=0 ; j < nFields; j++) {
+ if (PQgetlength(res,i,j) > fLength[j])
+ fLength[j] = PQgetlength(res,i,j);
+ }
+ }
}
if (printHeader) {
- /* first, print out the attribute names */
- for (i=0; i < nFields; i++) {
- fputs(PQfname(res,i), fp);
- if (fillAlign)
- fill (strlen (PQfname(res,i)), fLength[i], ' ', fp);
- fputs(fieldSep,fp);
- }
- fprintf(fp, "\n");
+ /* first, print out the attribute names */
+ for (i=0; i < nFields; i++) {
+ fputs(PQfname(res,i), fp);
+ if (fillAlign)
+ fill (strlen (PQfname(res,i)), fLength[i], ' ', fp);
+ fputs(fieldSep,fp);
+ }
+ fprintf(fp, "\n");
- /* Underline the attribute names */
- for (i=0; i < nFields; i++) {
- if (fillAlign)
- fill (0, fLength[i], '-', fp);
- fputs(fieldSep,fp);
- }
- fprintf(fp, "\n");
+ /* Underline the attribute names */
+ for (i=0; i < nFields; i++) {
+ if (fillAlign)
+ fill (0, fLength[i], '-', fp);
+ fputs(fieldSep,fp);
+ }
+ fprintf(fp, "\n");
}
/* next, print out the instances */
for (i=0; i < nTuples; i++) {
for (j=0 ; j < nFields; j++) {
fprintf(fp, "%s", PQgetvalue(res,i,j));
- if (fillAlign)
- fill (strlen (PQgetvalue(res,i,j)), fLength[j], ' ', fp);
- fputs(fieldSep,fp);
+ if (fillAlign)
+ fill (strlen (PQgetvalue(res,i,j)), fLength[j], ' ', fp);
+ fputs(fieldSep,fp);
}
fprintf(fp, "\n");
}
if (!quiet)
- fprintf (fp, "\nQuery returned %d row%s.\n",PQntuples(res),
- (PQntuples(res) == 1) ? "" : "s");
+ fprintf (fp, "\nQuery returned %d row%s.\n",PQntuples(res),
+ (PQntuples(res) == 1) ? "" : "s");
fflush(fp);
}
@@ -792,11 +793,11 @@ PQdisplayTuples(PGresult *res,
*/
void
PQprintTuples(PGresult *res,
- FILE* fout, /* output stream */
- int PrintAttNames,/* print attribute names or not*/
- int TerseOutput, /* delimiter bars or not?*/
- int colWidth /* width of column, if 0, use variable width */
- )
+ FILE* fout, /* output stream */
+ int PrintAttNames,/* print attribute names or not*/
+ int TerseOutput, /* delimiter bars or not?*/
+ int colWidth /* width of column, if 0, use variable width */
+ )
{
int nFields;
int nTups;
@@ -813,426 +814,464 @@ PQprintTuples(PGresult *res,
} else
sprintf(formatString,"%%s %%s");
- if ( nFields > 0 ) { /* only print tuples with at least 1 field. */
-
- if (!TerseOutput)
- {
- int width;
- width = nFields * 14;
- tborder = malloc (width+1);
- for (i = 0; i <= width; i++)
- tborder[i] = '-';
- tborder[i] = '\0';
- fprintf(fout,"%s\n",tborder);
- }
-
- for (i=0; i < nFields; i++) {
- if (PrintAttNames) {
- fprintf(fout,formatString,
- TerseOutput ? "" : "|",
- PQfname(res, i));
- }
- }
-
- if (PrintAttNames) {
- if (TerseOutput)
- fprintf(fout,"\n");
- else
- fprintf(fout, "|\n%s\n",tborder);
- }
-
- for (i = 0; i < nTups; i++) {
- for (j = 0; j < nFields; j++) {
- char *pval = PQgetvalue(res,i,j);
- fprintf(fout, formatString,
- TerseOutput ? "" : "|",
- pval ? pval : "");
- }
- if (TerseOutput)
- fprintf(fout,"\n");
- else
- fprintf(fout, "|\n%s\n",tborder);
- }
+ if ( nFields > 0 ) { /* only print rows with at least 1 field. */
+
+ if (!TerseOutput)
+ {
+ int width;
+ width = nFields * 14;
+ tborder = malloc (width+1);
+ for (i = 0; i <= width; i++)
+ tborder[i] = '-';
+ tborder[i] = '\0';
+ fprintf(fout,"%s\n",tborder);
+ }
+
+ for (i=0; i < nFields; i++) {
+ if (PrintAttNames) {
+ fprintf(fout,formatString,
+ TerseOutput ? "" : "|",
+ PQfname(res, i));
+ }
+ }
+
+ if (PrintAttNames) {
+ if (TerseOutput)
+ fprintf(fout,"\n");
+ else
+ fprintf(fout, "|\n%s\n",tborder);
+ }
+
+ for (i = 0; i < nTups; i++) {
+ for (j = 0; j < nFields; j++) {
+ char *pval = PQgetvalue(res,i,j);
+ fprintf(fout, formatString,
+ TerseOutput ? "" : "|",
+ pval ? pval : "");
+ }
+ if (TerseOutput)
+ fprintf(fout,"\n");
+ else
+ fprintf(fout, "|\n%s\n",tborder);
+ }
+ }
+}
+
+
+
+static void
+do_field(PQprintOpt *po, PGresult *res,
+ const int i, const int j, char *buf, const int fs_len,
+ char *fields[],
+ const int nFields, char *fieldNames[],
+ unsigned char fieldNotNum[], int fieldMax[],
+ const int fieldMaxLen, FILE *fout
+ ) {
+
+ char *pval, *p, *o;
+ int plen;
+ bool skipit;
+
+ plen=PQgetlength(res,i,j);
+ pval=PQgetvalue(res,i,j);
+
+ if (plen < 1 || !pval || !*pval) {
+ if (po->align || po->expanded) skipit = true;
+ else {
+ skipit = false;
+ goto efield;
+ }
+ } else skipit = false;
+
+ if (!skipit) {
+ for (p=pval, o=buf; *p; *(o++)=*(p++)) {
+ if ((fs_len==1 && (*p==*(po->fieldSep))) || *p=='\\')
+ *(o++)='\\';
+ if (po->align && (*pval=='E' || *pval=='e' ||
+ !((*p>='0' && *p<='9') ||
+ *p=='.' ||
+ *p=='E' ||
+ *p=='e' ||
+ *p==' ' ||
+ *p=='-')))
+ fieldNotNum[j]=1;
+ }
+ *o='\0';
+ if (!po->expanded && (po->align || po->html3)) {
+ int n=strlen(buf);
+ if (n>fieldMax[j])
+ fieldMax[j]=n;
+ if (!(fields[i*nFields+j]=(char *)malloc(n+1))) {
+ perror("malloc");
+ exit(1);
+ }
+ strcpy(fields[i*nFields+j], buf);
+ } else {
+ if (po->expanded) {
+ if (po->html3)
+ fprintf(fout,
+ "<tr><td align=left><b>%s</b></td>"
+ "<td align=%s>%s</td></tr>\n",
+ fieldNames[j],
+ fieldNotNum[j] ? "left": "right",
+ buf);
+ else {
+ if (po->align)
+ fprintf(fout,
+ "%-*s%s %s\n",
+ fieldMaxLen-fs_len, fieldNames[j], po->fieldSep,
+ buf);
+ else
+ fprintf(fout, "%s%s%s\n", fieldNames[j], po->fieldSep, buf);
+ }
+ } else {
+ if (!po->html3) {
+ fputs(buf, fout);
+ efield:
+ if ((j+1)<nFields)
+ fputs(po->fieldSep, fout);
+ else
+ fputc('\n', fout);
+ }
+ }
+ }
}
}
+
+static void
+do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[],
+ char *fieldNames[], unsigned char fieldNotNum[],
+ const int fs_len, char *border, PGresult *res) {
+
+ int j; /* for loop index */
+
+ if (po->html3)
+ fputs("<tr>", fout);
+ else {
+ int j; /* for loop index */
+ int tot=0;
+ int n=0;
+ char *p;
+ for (; n < nFields; n++)
+ tot+=fieldMax[n]+fs_len+(po->standard? 2: 0);
+ if (po->standard)
+ tot+=fs_len*2+2;
+ if (!(p=border=malloc(tot+1))) {
+ perror("malloc");
+ exit(1);
+ }
+ if (po->standard) {
+ char *fs=po->fieldSep;
+ while (*fs++)
+ *p++='+';
+ }
+ for (j=0; j < nFields; j++) {
+ int len;
+ for (len=fieldMax[j] + (po->standard? 2:0) ; len--; *p++='-');
+ if (po->standard || (j+1)<nFields) {
+ char *fs=po->fieldSep;
+ while (*fs++)
+ *p++='+';
+ }
+ }
+ *p='\0';
+ if (po->standard)
+ fprintf(fout, "%s\n", border);
+ }
+ if (po->standard)
+ fputs(po->fieldSep, fout);
+ for (j=0; j < nFields; j++) {
+ char *s=PQfname(res, j);
+ if (po->html3) {
+ fprintf(fout, "<th align=%s>%s</th>",
+ fieldNotNum[j]? "left": "right", fieldNames[j]);
+ } else {
+ int n=strlen(s);
+ if (n>fieldMax[j])
+ fieldMax[j]=n;
+ if (po->standard)
+ fprintf(fout,
+ fieldNotNum[j] ? " %-*s ": " %*s ",
+ fieldMax[j], s);
+ else
+ fprintf(fout, fieldNotNum[j] ? "%-*s": "%*s", fieldMax[j], s);
+ if (po->standard || (j+1)<nFields)
+ fputs(po->fieldSep, fout);
+ }
+ }
+ if (po->html3)
+ fputs("</tr>\n", fout);
+ else
+ fprintf(fout, "\n%s\n", border);
+}
+
+
+static void
+output_row(FILE *fout, PQprintOpt *po, const int nFields, char *fields[],
+ unsigned char fieldNotNum[], int fieldMax[], char *border,
+ const int row_index) {
+
+ int field_index; /* for loop index */
+
+ if (po->html3)
+ fputs("<tr>", fout);
+ else if (po->standard)
+ fputs(po->fieldSep, fout);
+ for (field_index = 0; field_index < nFields; field_index++) {
+ char *p=fields[row_index*nFields+field_index];
+ if (po->html3)
+ fprintf(fout, "<td align=%s>%s</td>",
+ fieldNotNum[field_index]? "left": "right", p? p: "");
+ else {
+ fprintf(fout,
+ fieldNotNum[field_index] ?
+ (po->standard ? " %-*s ": "%-*s") :
+ (po->standard ? " %*s ": "%*s"),
+ fieldMax[field_index],
+ p ? p: "");
+ if (po->standard || field_index+1 < nFields)
+ fputs(po->fieldSep, fout);
+ }
+ if (p)
+ free(p);
+ }
+ if (po->html3)
+ fputs("</tr>", fout);
+ else
+ if (po->standard)
+ fprintf(fout, "\n%s", border);
+ fputc('\n', fout);
+}
+
+
+
+
/*
* PQprint()
*
- * new PQprintTuples routine (proff@suburbia.net)
+ * Format results of a query for printing.
+ *
* PQprintOpt is a typedef (structure) that containes
* various flags and options. consult libpq-fe.h for
* details
+ *
+ * Obsoletes PQprintTuples.
*/
void
PQprint(FILE *fout,
PGresult *res,
- PQprintOpt *po
+ PQprintOpt *po
)
{
int nFields;
nFields = PQnfields(res);
- if ( nFields > 0 ) { /* only print tuples with at least 1 field. */
- int i,j;
- int nTups;
- int *fieldMax=NULL; /* in case we don't use them */
- unsigned char *fieldNotNum=NULL;
- char *border=NULL;
- char **fields=NULL;
- char **fieldNames;
- int fieldMaxLen=0;
- int numFieldName;
- int fs_len=strlen(po->fieldSep);
- int total_line_length = 0;
- int usePipe = 0;
- char *pagerenv;
- char buf[8192*2+1];
-
- nTups = PQntuples(res);
- if (!(fieldNames=(char **)calloc(nFields, sizeof (char *))))
- {
- perror("calloc");
- exit(1);
- }
- if (!(fieldNotNum=(unsigned char *)calloc(nFields, 1)))
- {
- perror("calloc");
- exit(1);
- }
- if (!(fieldMax=(int *)calloc(nFields, sizeof(int))))
- {
- perror("calloc");
- exit(1);
- }
- for (numFieldName=0; po->fieldName && po->fieldName[numFieldName]; numFieldName++)
- ;
- for (j=0; j < nFields; j++)
- {
- int len;
- char *s=(j<numFieldName && po->fieldName[j][0])? po->fieldName[j]: PQfname(res, j);
- fieldNames[j]=s;
- len=s? strlen(s): 0;
- fieldMax[j] = len;
- /*
- if (po->header && len<5)
- len=5;
- */
- len+=fs_len;
- if (len>fieldMaxLen)
- fieldMaxLen=len;
- total_line_length += len;
- }
+ if ( nFields > 0 ) { /* only print rows with at least 1 field. */
+ int i,j;
+ int nTups;
+ int *fieldMax=NULL; /* in case we don't use them */
+ unsigned char *fieldNotNum=NULL;
+ char *border=NULL;
+ char **fields=NULL;
+ char **fieldNames;
+ int fieldMaxLen=0;
+ int numFieldName;
+ int fs_len=strlen(po->fieldSep);
+ int total_line_length = 0;
+ int usePipe = 0;
+ char *pagerenv;
+ char buf[8192*2+1];
+
+ nTups = PQntuples(res);
+ if (!(fieldNames=(char **)calloc(nFields, sizeof (char *)))) {
+ perror("calloc");
+ exit(1);
+ }
+ if (!(fieldNotNum=(unsigned char *)calloc(nFields, 1))) {
+ perror("calloc");
+ exit(1);
+ }
+ if (!(fieldMax=(int *)calloc(nFields, sizeof(int)))) {
+ perror("calloc");
+ exit(1);
+ }
+ for (numFieldName=0;
+ po->fieldName && po->fieldName[numFieldName];
+ numFieldName++)
+ ;
+ for (j=0; j < nFields; j++) {
+ int len;
+ char *s =
+ (j<numFieldName && po->fieldName[j][0])?
+ po->fieldName[j]: PQfname(res, j);
+ fieldNames[j]=s;
+ len=s ? strlen(s): 0;
+ fieldMax[j] = len;
+ len+=fs_len;
+ if (len>fieldMaxLen)
+ fieldMaxLen=len;
+ total_line_length += len;
+ }
- total_line_length += nFields * strlen(po->fieldSep) + 1;
+ total_line_length += nFields * strlen(po->fieldSep) + 1;
- if (fout == NULL)
- fout = stdout;
- if (po->pager && fout == stdout &&
- isatty(fileno(stdin)) &&
- isatty(fileno(stdout)))
- {
- /* try to pipe to the pager program if possible */
+ if (fout == NULL)
+ fout = stdout;
+ if (po->pager && fout == stdout &&
+ isatty(fileno(stdin)) &&
+ isatty(fileno(stdout))) {
+ /* try to pipe to the pager program if possible */
#ifdef TIOCGWINSZ
- if (ioctl(fileno(stdout),TIOCGWINSZ,&screen_size) == -1 ||
- screen_size.ws_col == 0 ||
- screen_size.ws_row == 0)
- {
+ if (ioctl(fileno(stdout),TIOCGWINSZ,&screen_size) == -1 ||
+ screen_size.ws_col == 0 ||
+ screen_size.ws_row == 0) {
#endif
- screen_size.ws_row = 24;
- screen_size.ws_col = 80;
+ screen_size.ws_row = 24;
+ screen_size.ws_col = 80;
#ifdef TIOCGWINSZ
- }
+ }
#endif
- pagerenv=getenv("PAGER");
- if (pagerenv != NULL &&
- pagerenv[0] != '\0' &&
- !po->html3 &&
- ((po->expanded &&
- nTups * (nFields+1) >= screen_size.ws_row) ||
- (!po->expanded &&
- nTups * (total_line_length / screen_size.ws_col + 1) *
- ( 1 + (po->standard != 0)) >=
- screen_size.ws_row -
- (po->header != 0) *
- (total_line_length / screen_size.ws_col + 1) * 2
- - (po->header != 0) *2 /* row count and newline */
- )))
- {
- fout = popen(pagerenv, "w");
- if (fout) {
- usePipe = 1;
- signal(SIGPIPE, SIG_IGN);
- } else
- fout = stdout;
- }
- }
-
- if (!po->expanded && (po->align || po->html3))
- {
- if (!(fields=(char **)calloc(nFields*(nTups+1), sizeof(char *))))
- {
- perror("calloc");
- exit(1);
- }
- }
- else
- if (po->header && !po->html3)
- {
- if (po->expanded)
- {
- if (po->align)
- fprintf(fout, "%-*s%s Value\n", fieldMaxLen-fs_len, "Field", po->fieldSep);
- else
- fprintf(fout, "%s%sValue\n", "Field", po->fieldSep);
- }
- else
- {
- int len=0;
- for (j=0; j < nFields; j++)
- {
- char *s=fieldNames[j];
- fputs(s, fout);
- len+=strlen(s)+fs_len;
- if ((j+1)<nFields)
- fputs(po->fieldSep, fout);
- }
- fputc('\n', fout);
- for (len-=fs_len; len--; fputc('-', fout));
- fputc('\n', fout);
- }
- }
- if (po->expanded && po->html3)
- {
- if (po->caption)
- fprintf(fout, "<centre><h2>%s</h2></centre>\n", po->caption);
- else
- fprintf(fout, "<centre><h2>Query retrieved %d tuples * %d fields</h2></centre>\n", nTups, nFields);
- }
- for (i = 0; i < nTups; i++)
- {
- if (po->expanded)
- {
- if (po->html3)
- fprintf(fout, "<table %s><caption align=high>%d</caption>\n", po->tableOpt? po->tableOpt: "", i);
- else
- fprintf(fout, "-- RECORD %d --\n", i);
- }
+ pagerenv=getenv("PAGER");
+ if (pagerenv != NULL &&
+ pagerenv[0] != '\0' &&
+ !po->html3 &&
+ ((po->expanded &&
+ nTups * (nFields+1) >= screen_size.ws_row) ||
+ (!po->expanded &&
+ nTups * (total_line_length / screen_size.ws_col + 1) *
+ ( 1 + (po->standard != 0)) >=
+ screen_size.ws_row -
+ (po->header != 0) *
+ (total_line_length / screen_size.ws_col + 1) * 2
+ - (po->header != 0) *2 /* row count and newline */
+ ))) {
+ fout = popen(pagerenv, "w");
+ if (fout) {
+ usePipe = 1;
+ signal(SIGPIPE, SIG_IGN);
+ } else
+ fout = stdout;
+ }
+ }
+
+ if (!po->expanded && (po->align || po->html3)) {
+ if (!(fields=(char **)calloc(nFields*(nTups+1), sizeof(char *)))) {
+ perror("calloc");
+ exit(1);
+ }
+ } else
+ if (po->header && !po->html3) {
+ if (po->expanded) {
+ if (po->align)
+ fprintf(fout, "%-*s%s Value\n",
+ fieldMaxLen-fs_len, "Field", po->fieldSep);
+ else
+ fprintf(fout, "%s%sValue\n", "Field", po->fieldSep);
+ } else {
+ int len=0;
+ for (j=0; j < nFields; j++) {
+ char *s=fieldNames[j];
+ fputs(s, fout);
+ len+=strlen(s)+fs_len;
+ if ((j+1)<nFields)
+ fputs(po->fieldSep, fout);
+ }
+ fputc('\n', fout);
+ for (len-=fs_len; len--; fputc('-', fout));
+ fputc('\n', fout);
+ }
+ }
+ if (po->expanded && po->html3) {
+ if (po->caption)
+ fprintf(fout, "<centre><h2>%s</h2></centre>\n", po->caption);
+ else
+ fprintf(fout,
+ "<centre><h2>"
+ "Query retrieved %d rows * %d fields"
+ "</h2></centre>\n",
+ nTups, nFields);
+ }
+ for (i = 0; i < nTups; i++) {
+ if (po->expanded) {
+ if (po->html3)
+ fprintf(fout,
+ "<table %s><caption align=high>%d</caption>\n",
+ po->tableOpt? po->tableOpt: "", i);
+ else
+ fprintf(fout, "-- RECORD %d --\n", i);
+ }
for (j = 0; j < nFields; j++)
- {
- char *pval, *p, *o;
- int plen;
- if ((plen=PQgetlength(res,i,j))<1 || !(pval=PQgetvalue(res,i,j)) || !*pval)
- {
- if (po->align || po->expanded)
- continue;
- goto efield;
- }
- for (p=pval, o=buf; *p; *(o++)=*(p++))
- {
- if ((fs_len==1 && (*p==*(po->fieldSep))) || *p=='\\')
- *(o++)='\\';
- if (po->align && (*pval=='E' || *pval=='e' ||
- !((*p>='0' && *p<='9') || *p=='.' || *p=='E' || *p=='e' || *p==' ' || *p=='-')))
- fieldNotNum[j]=1;
- }
- *o='\0';
- if (!po->expanded && (po->align || po->html3))
- {
- int n=strlen(buf);
- if (n>fieldMax[j])
- fieldMax[j]=n;
- if (!(fields[i*nFields+j]=(char *)malloc(n+1)))
- {
- perror("malloc");
- exit(1);
- }
- strcpy(fields[i*nFields+j], buf);
- }
- else
- {
- if (po->expanded)
- {
- if (po->html3)
- fprintf(fout, "<tr><td align=left><b>%s</b></td><td align=%s>%s</td></tr>\n",
- fieldNames[j], fieldNotNum[j]? "left": "right", buf);
- else
- {
- if (po->align)
- fprintf(fout, "%-*s%s %s\n", fieldMaxLen-fs_len, fieldNames[j], po->fieldSep, buf);
- else
- fprintf(fout, "%s%s%s\n", fieldNames[j], po->fieldSep, buf);
- }
- }
- else
- {
- if (!po->html3)
- {
- fputs(buf, fout);
-efield:
- if ((j+1)<nFields)
- fputs(po->fieldSep, fout);
- else
- fputc('\n', fout);
- }
- }
- }
- }
- if (po->html3 && po->expanded)
- fputs("</table>\n", fout);
- }
- if (!po->expanded && (po->align || po->html3))
- {
- if (po->html3)
- {
- if (po->header)
- {
- if (po->caption)
- fprintf(fout, "<table %s><caption align=high>%s</caption>\n", po->tableOpt? po->tableOpt: "", po->caption);
- else
- fprintf(fout, "<table %s><caption align=high>Retrieved %d tuples * %d fields</caption>\n", po->tableOpt? po->tableOpt: "", nTups, nFields);
- } else
- fprintf(fout, "<table %s>", po->tableOpt? po->tableOpt: "");
- }
- if (po->header)
- {
- if (po->html3)
- fputs("<tr>", fout);
- else
- {
- int tot=0;
- int n=0;
- char *p;
- for (; n<nFields; n++)
- tot+=fieldMax[n]+fs_len+(po->standard? 2: 0);
- if (po->standard)
- tot+=fs_len*2+2;
- if (!(p=border=malloc(tot+1)))
- {
- perror("malloc");
- exit(1);
- }
- if (po->standard)
- {
- char *fs=po->fieldSep;
- while (*fs++)
- *p++='+';
- }
- for (j=0; j <nFields; j++)
- {
- int len;
- for (len=fieldMax[j] + (po->standard? 2:0) ; len--; *p++='-');
- if (po->standard || (j+1)<nFields)
- {
- char *fs=po->fieldSep;
- while (*fs++)
- *p++='+';
- }
- }
- *p='\0';
- if (po->standard)
- fprintf(fout, "%s\n", border);
- }
- if (po->standard)
- fputs(po->fieldSep, fout);
- for (j=0; j < nFields; j++)
- {
- char *s=PQfname(res, j);
- if (po->html3)
- {
- fprintf(fout, "<th align=%s>%s</th>", fieldNotNum[j]? "left": "right",
- fieldNames[j]);
- }
- else
- {
- int n=strlen(s);
- if (n>fieldMax[j])
- fieldMax[j]=n;
- if (po->standard)
- fprintf(fout, fieldNotNum[j]? " %-*s ": " %*s ", fieldMax[j], s);
- else
- fprintf(fout, fieldNotNum[j]? "%-*s": "%*s", fieldMax[j], s);
- if (po->standard || (j+1)<nFields)
- fputs(po->fieldSep, fout);
- }
- }
- if (po->html3)
- fputs("</tr>\n", fout);
- else
- fprintf(fout, "\n%s\n", border);
- }
- for (i = 0; i < nTups; i++)
- {
- if (po->html3)
- fputs("<tr>", fout);
- else
- if (po->standard)
- fputs(po->fieldSep, fout);
-
- for (j = 0; j < nFields; j++)
- {
- char *p=fields[i*nFields+j];
- if (po->html3)
- fprintf(fout, "<td align=%s>%s</td>", fieldNotNum[j]? "left": "right", p? p: "");
-
- else
- {
- fprintf(fout, fieldNotNum[j]? (po->standard? " %-*s ": "%-*s"): (po->standard? " %*s ": "%*s"), fieldMax[j], p? p: "");
- if (po->standard || (j+1)<nFields)
- fputs(po->fieldSep, fout);
- }
- if (p)
- free(p);
- }
- if (po->html3)
- fputs("</tr>", fout);
- else
- if (po->standard)
- fprintf(fout, "\n%s", border);
- fputc('\n', fout);
- }
- free(fields);
- }
- if (po->header && !po->html3)
- fprintf (fout, "(%d row%s)\n\n",PQntuples(res),
- (PQntuples(res) == 1) ? "" : "s");
- free(fieldMax);
- free(fieldNotNum);
- free(fieldNames);
- if (usePipe)
- {
- pclose(fout);
- signal(SIGPIPE, SIG_DFL);
- }
- if (border)
- free(border);
- if (po->html3 && !po->expanded)
- fputs("</table>\n", fout);
- }
+ do_field(po, res, i, j, buf, fs_len, fields, nFields,
+ fieldNames, fieldNotNum,
+ fieldMax, fieldMaxLen, fout);
+ if (po->html3 && po->expanded)
+ fputs("</table>\n", fout);
+ }
+ if (!po->expanded && (po->align || po->html3)) {
+ if (po->html3) {
+ if (po->header) {
+ if (po->caption)
+ fprintf(fout,
+ "<table %s><caption align=high>%s</caption>\n",
+ po->tableOpt? po->tableOpt: "",
+ po->caption);
+ else
+ fprintf(fout,
+ "<table %s><caption align=high>"
+ "Retrieved %d rows * %d fields"
+ "</caption>\n",
+ po->tableOpt? po->tableOpt: "", nTups, nFields);
+ } else
+ fprintf(fout, "<table %s>", po->tableOpt? po->tableOpt: "");
+ }
+ if (po->header)
+ do_header(fout, po, nFields, fieldMax, fieldNames, fieldNotNum,
+ fs_len, border, res);
+ for (i = 0; i < nTups; i++)
+ output_row(fout, po, nFields, fields,
+ fieldNotNum, fieldMax, border, i);
+ free(fields);
+ }
+ if (po->header && !po->html3)
+ fprintf (fout, "(%d row%s)\n\n",PQntuples(res),
+ (PQntuples(res) == 1) ? "" : "s");
+ free(fieldMax);
+ free(fieldNotNum);
+ free(fieldNames);
+ if (usePipe) {
+ pclose(fout);
+ signal(SIGPIPE, SIG_DFL);
+ }
+ if (border)
+ free(border);
+ if (po->html3 && !po->expanded)
+ fputs("</table>\n", fout);
+ }
}
/* ----------------
- * PQfn - Send a function call to the POSTGRES backend.
+ * PQfn - Send a function call to the POSTGRES backend.
*
* conn : backend connection
- * fnid : function id
- * result_buf : pointer to result buffer (&int if integer)
- * result_len : length of return value.
+ * fnid : function id
+ * result_buf : pointer to result buffer (&int if integer)
+ * result_len : length of return value.
* actual_result_len: actual length returned. (differs from result_len
- * for varlena structures.)
+ * for varlena structures.)
* result_type : If the result is an integer, this must be 1,
* otherwise this should be 0
- * args : pointer to a NULL terminated arg array.
- * (length, if integer, and result-pointer)
- * nargs : # of arguments in args array.
+ * args : pointer to a NULL terminated arg array.
+ * (length, if integer, and result-pointer)
+ * nargs : # of arguments in args array.
*
* RETURNS
- * NULL on failure. PQerrormsg will be set.
- * "G" if there is a return value.
- * "V" if there is no return value.
+ * NULL on failure. PQerrormsg will be set.
+ * "G" if there is a return value.
+ * "V" if there is no return value.
* ----------------
*/
@@ -1260,64 +1299,66 @@ PQfn(PGconn *conn,
pqPuts("F ",pfout,pfdebug); /* function */
pqPutInt(fnid, 4, pfout, pfdebug); /* function id */
- pqPutInt(nargs, 4, pfout, pfdebug); /* # of args */
-
- for (i = 0; i < nargs; ++i) { /* len.int4 + contents */
- pqPutInt(args[i].len, 4, pfout, pfdebug);
- if (args[i].isint) {
- pqPutInt(args[i].u.integer, 4, pfout, pfdebug);
- } else {
- pqPutnchar((char *)args[i].u.ptr, args[i].len, pfout, pfdebug);
- }
+ pqPutInt(nargs, 4, pfout, pfdebug); /* # of args */
+
+ for (i = 0; i < nargs; ++i) { /* len.int4 + contents */
+ pqPutInt(args[i].len, 4, pfout, pfdebug);
+ if (args[i].isint) {
+ pqPutInt(args[i].u.integer, 4, pfout, pfdebug);
+ } else {
+ pqPutnchar((char *)args[i].u.ptr, args[i].len, pfout, pfdebug);
+ }
}
pqFlush(pfout, pfdebug);
id = pqGetc(pfin, pfdebug);
if (id != 'V') {
- if (id == 'E') {
- pqGets(conn->errorMessage,ERROR_MSG_LENGTH,pfin,pfdebug);
- } else
- sprintf(conn->errorMessage,
- "PQfn: expected a 'V' from the backend. Got '%c' instead",
- id);
- return makeEmptyPGresult(conn,PGRES_FATAL_ERROR);
+ if (id == 'E') {
+ pqGets(conn->errorMessage,ERROR_MSG_LENGTH,pfin,pfdebug);
+ } else
+ sprintf(conn->errorMessage,
+ "PQfn: expected a 'V' from the backend. Got '%c' instead",
+ id);
+ return makeEmptyPGresult(conn,PGRES_FATAL_ERROR);
}
id = pqGetc(pfin, pfdebug);
for (;;) {
- int c;
- switch (id) {
- case 'G': /* function returned properly */
- pqGetInt(actual_result_len,4,pfin,pfdebug);
- if (result_is_int) {
- pqGetInt(result_buf,4,pfin,pfdebug);
- } else {
- pqGetnchar((char *) result_buf, *actual_result_len,
- pfin, pfdebug);
- }
- c = pqGetc(pfin, pfdebug); /* get the last '0'*/
- return makeEmptyPGresult(conn,PGRES_COMMAND_OK);
- case 'E':
- sprintf(conn->errorMessage,
- "PQfn: returned an error");
- return makeEmptyPGresult(conn,PGRES_FATAL_ERROR);
- case 'N':
- /* print notice and go back to processing return values */
- if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) {
- sprintf(conn->errorMessage,
- "Notice return detected from backend, but error message cannot be read");
- } else
- fprintf(stderr, "%s\n", conn->errorMessage);
- /* keep iterating */
- break;
- case '0': /* no return value */
- return makeEmptyPGresult(conn,PGRES_COMMAND_OK);
- default:
- /* The backend violates the protocol. */
- sprintf(conn->errorMessage,
- "FATAL: PQfn: protocol error: id=%x\n", id);
- return makeEmptyPGresult(conn,PGRES_FATAL_ERROR);
- }
+ int c;
+ switch (id) {
+ case 'G': /* function returned properly */
+ pqGetInt(actual_result_len,4,pfin,pfdebug);
+ if (result_is_int) {
+ pqGetInt(result_buf,4,pfin,pfdebug);
+ } else {
+ pqGetnchar((char *) result_buf, *actual_result_len,
+ pfin, pfdebug);
+ }
+ c = pqGetc(pfin, pfdebug); /* get the last '0'*/
+ return makeEmptyPGresult(conn,PGRES_COMMAND_OK);
+ case 'E':
+ sprintf(conn->errorMessage,
+ "PQfn: returned an error");
+ return makeEmptyPGresult(conn,PGRES_FATAL_ERROR);
+ case 'N':
+ /* print notice and go back to processing return values */
+ if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug)
+ == 1) {
+ sprintf(conn->errorMessage,
+ "Notice return detected from backend, but message "
+ "cannot be read");
+ } else
+ fprintf(stderr, "%s\n", conn->errorMessage);
+ /* keep iterating */
+ break;
+ case '0': /* no return value */
+ return makeEmptyPGresult(conn,PGRES_COMMAND_OK);
+ default:
+ /* The backend violates the protocol. */
+ sprintf(conn->errorMessage,
+ "FATAL: PQfn: protocol error: id=%x\n", id);
+ return makeEmptyPGresult(conn,PGRES_FATAL_ERROR);
+ }
}
}
@@ -1366,15 +1407,15 @@ PQfname(PGresult *res, int field_num)
}
if (field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQfname: ERROR! name of field %d(of %d) is not available",
- field_num, res->numAttributes -1);
- return NULL;
+ fprintf(stderr,
+ "PQfname: ERROR! name of field %d(of %d) is not available",
+ field_num, res->numAttributes -1);
+ return NULL;
}
if (res->attDescs) {
- return res->attDescs[field_num].name;
+ return res->attDescs[field_num].name;
} else
- return NULL;
+ return NULL;
}
/*
@@ -1412,14 +1453,14 @@ PQftype(PGresult *res, int field_num)
}
if (field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQftype: ERROR! type of field %d(of %d) is not available",
- field_num, res->numAttributes -1);
+ fprintf(stderr,
+ "PQftype: ERROR! type of field %d(of %d) is not available",
+ field_num, res->numAttributes -1);
}
if (res->attDescs) {
- return res->attDescs[field_num].adtid;
+ return res->attDescs[field_num].adtid;
} else
- return InvalidOid;
+ return InvalidOid;
}
int2
@@ -1431,14 +1472,14 @@ PQfsize(PGresult *res, int field_num)
}
if (field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQfsize: ERROR! size of field %d(of %d) is not available",
- field_num, res->numAttributes -1);
+ fprintf(stderr,
+ "PQfsize: ERROR! size of field %d(of %d) is not available",
+ field_num, res->numAttributes -1);
}
if (res->attDescs) {
- return res->attDescs[field_num].adtsize;
+ return res->attDescs[field_num].adtsize;
} else
- return 0;
+ return 0;
}
char* PQcmdStatus(PGresult *res) {
@@ -1472,7 +1513,7 @@ const char* PQoidStatus(PGresult *res) {
/*
PQgetvalue:
return the attribute value of field 'field_num' of
- tuple 'tup_num'
+ row 'tup_num'
If res is binary, then the value returned is NOT a null-terminated
ASCII string, but the binary representation in the server's native
@@ -1489,10 +1530,11 @@ PQgetvalue(PGresult *res, int tup_num, int field_num)
}
if (tup_num > (res->ntups - 1) ||
- field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQgetvalue: ERROR! field %d(of %d) of tuple %d(of %d) is not available",
- field_num, res->numAttributes - 1, tup_num, res->ntups);
+ field_num > (res->numAttributes - 1)) {
+ fprintf(stderr,
+ "PQgetvalue: ERROR! field %d(of %d) of row %d(of %d) "
+ "is not available",
+ field_num, res->numAttributes - 1, tup_num, res->ntups);
}
return res->tuples[tup_num][field_num].value;
@@ -1512,16 +1554,17 @@ PQgetlength(PGresult *res, int tup_num, int field_num)
}
if (tup_num > (res->ntups - 1 )||
- field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQgetlength: ERROR! field %d(of %d) of tuple %d(of %d) is not available",
- field_num, res->numAttributes - 1, tup_num, res->ntups);
+ field_num > (res->numAttributes - 1)) {
+ fprintf(stderr,
+ "PQgetlength: ERROR! field %d(of %d) of row %d(of %d) "
+ "is not available",
+ field_num, res->numAttributes - 1, tup_num, res->ntups);
}
if (res->tuples[tup_num][field_num].len != NULL_LEN)
- return res->tuples[tup_num][field_num].len;
+ return res->tuples[tup_num][field_num].len;
else
- return 0;
+ return 0;
}
/* PQgetisnull:
@@ -1536,16 +1579,15 @@ PQgetisnull(PGresult *res, int tup_num, int field_num)
}
if (tup_num > (res->ntups - 1 )||
- field_num > (res->numAttributes - 1)) {
- fprintf(stderr,
- "PQgetisnull: ERROR! field %d(of %d) of tuple %d(of %d) is not available",
- field_num, res->numAttributes - 1, tup_num, res->ntups);
+ field_num > (res->numAttributes - 1)) {
+ fprintf(stderr,
+ "PQgetisnull: ERROR! field %d(of %d) of row %d(of %d) "
+ "is not available",
+ field_num, res->numAttributes - 1, tup_num, res->ntups);
}
if (res->tuples[tup_num][field_num].len == NULL_LEN)
- return 1;
+ return 1;
else
- return 0;
+ return 0;
}
-
-