1
0
mirror of https://github.com/postgres/postgres.git synced 2025-10-31 10:30:33 +03:00

Date: Sun, 16 Aug 1998 14:56:48 -0400

From: Tom Lane <tgl@sss.pgh.pa.us>
Attached is a patch for this weekend's work on libpq.  I've dealt
with several issues:

        <for details: see message, in pgsql-patches archive for above data>
This commit is contained in:
Marc G. Fournier
1998-08-17 03:50:43 +00:00
parent 3fa676a74c
commit 9312033071
16 changed files with 375 additions and 365 deletions

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.28 1998/07/09 03:32:09 scrappy Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.29 1998/08/17 03:50:22 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -485,9 +485,8 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
char *opt;
int i;
int tupno;
char prearrayInd[MAX_MESSAGE_LEN];
char arrayInd[MAX_MESSAGE_LEN];
char *arrVar;
char nameBuffer[256];
if (argc < 3 || argc > 5) {
Tcl_AppendResult(interp, "Wrong # of arguments\n",0);
@@ -522,6 +521,10 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
sprintf(interp->result, "%d", PQntuples(result));
return TCL_OK;
}
else if (strcmp(opt, "-numAttrs") == 0) {
sprintf(interp->result, "%d", PQnfields(result));
return TCL_OK;
}
else if (strcmp(opt, "-assign") == 0) {
if (argc != 4) {
Tcl_AppendResult(interp, "-assign option must be followed by a variable name",0);
@@ -530,17 +533,21 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
arrVar = argv[3];
/* this assignment assigns the table of result tuples into a giant
array with the name given in the argument,
the indices of the array or (tupno,attrName)*/
the indices of the array or (tupno,attrName).
Note we expect field names not to exceed a few dozen characters,
so truncating to prevent buffer overflow shouldn't be a problem.
*/
for (tupno = 0; tupno<PQntuples(result); tupno++) {
for (i=0;i<PQnfields(result);i++) {
sprintf(arrayInd, "%d,%s", tupno, PQfname(result,i));
Tcl_SetVar2(interp, arrVar, arrayInd,
sprintf(nameBuffer, "%d,%.200s", tupno, PQfname(result,i));
if (Tcl_SetVar2(interp, arrVar, nameBuffer,
#ifdef TCL_ARRAYS
tcl_value(PQgetvalue(result,tupno,i)),
tcl_value(PQgetvalue(result,tupno,i)),
#else
PQgetvalue(result,tupno,i),
PQgetvalue(result,tupno,i),
#endif
TCL_LEAVE_ERR_MSG);
TCL_LEAVE_ERR_MSG) == NULL)
return TCL_ERROR;
}
}
Tcl_AppendResult(interp, arrVar, 0);
@@ -554,15 +561,23 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
arrVar = argv[3];
/* this assignment assigns the table of result tuples into a giant
array with the name given in the argument,
the indices of the array or (tupno,attrName)*/
the indices of the array or (tupno,attrName).
Here, we still assume PQfname won't exceed 200 characters,
but we dare not make the same assumption about the data in field 0.
*/
for (tupno = 0; tupno<PQntuples(result); tupno++) {
sprintf(prearrayInd,"%s",PQgetvalue(result,tupno,0));
const char *field0 = PQgetvalue(result,tupno,0);
char * workspace = malloc(strlen(field0) + 210);
for (i=1;i<PQnfields(result);i++) {
sprintf(arrayInd, "%s,%s", prearrayInd, PQfname(result,i));
Tcl_SetVar2(interp, arrVar, arrayInd,
PQgetvalue(result,tupno,i),
TCL_LEAVE_ERR_MSG);
sprintf(workspace, "%s,%.200s", field0, PQfname(result,i));
if (Tcl_SetVar2(interp, arrVar, workspace,
PQgetvalue(result,tupno,i),
TCL_LEAVE_ERR_MSG) == NULL) {
free(workspace);
return TCL_ERROR;
}
}
free(workspace);
}
Tcl_AppendResult(interp, arrVar, 0);
return TCL_OK;
@@ -573,25 +588,13 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR;
}
tupno = atoi(argv[3]);
if (tupno >= PQntuples(result)) {
if (tupno < 0 || tupno >= PQntuples(result)) {
Tcl_AppendResult(interp, "argument to getTuple cannot exceed number of tuples - 1",0);
return TCL_ERROR;
}
#ifdef TCL_ARRAYS
for (i=0; i<PQnfields(result); i++) {
Tcl_AppendElement(interp, tcl_value(PQgetvalue(result,tupno,i)));
Tcl_AppendElement(interp, PQgetvalue(result,tupno,i));
}
#else
/* Tcl_AppendResult(interp, PQgetvalue(result,tupno,0),NULL); */
Tcl_AppendElement(interp, PQgetvalue(result,tupno,0));
for (i=1;i<PQnfields(result);i++) {
/* Tcl_AppendResult(interp, " ", PQgetvalue(result,tupno,i),NULL);*/
Tcl_AppendElement(interp, PQgetvalue(result,tupno,i));
}
#endif
return TCL_OK;
}
else if (strcmp(opt, "-tupleArray") == 0) {
@@ -600,41 +603,42 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
return TCL_ERROR;
}
tupno = atoi(argv[3]);
if (tupno >= PQntuples(result)) {
if (tupno < 0 || tupno >= PQntuples(result)) {
Tcl_AppendResult(interp, "argument to tupleArray cannot exceed number of tuples - 1",0);
return TCL_ERROR;
}
for ( i = 0; i < PQnfields(result); i++) {
if (Tcl_SetVar2(interp, argv[4], PQfname(result, i), PQgetvalue(result, tupno, i), TCL_LEAVE_ERR_MSG) == NULL) {
if (Tcl_SetVar2(interp, argv[4], PQfname(result, i),
PQgetvalue(result, tupno, i),
TCL_LEAVE_ERR_MSG) == NULL) {
return TCL_ERROR;
}
}
return TCL_OK;
}
else if (strcmp(opt, "-attributes") == 0) {
Tcl_AppendResult(interp, PQfname(result,0),NULL);
for (i=1;i<PQnfields(result);i++) {
Tcl_AppendResult(interp, " ", PQfname(result,i), NULL);
for (i=0;i<PQnfields(result);i++) {
Tcl_AppendElement(interp, PQfname(result,i));
}
return TCL_OK;
}
else if (strcmp(opt, "-lAttributes") == 0) {
char buf[512];
Tcl_ResetResult(interp);
for (i = 0; i < PQnfields(result); i++) {
sprintf(buf, "{%s} %ld %d", PQfname(result, i),
(long) PQftype(result, i),
PQfsize(result, i));
Tcl_AppendElement(interp, buf);
/* start a sublist */
if (i > 0)
Tcl_AppendResult(interp, " {", 0);
else
Tcl_AppendResult(interp, "{", 0);
Tcl_AppendElement(interp, PQfname(result, i));
sprintf(nameBuffer, "%ld", (long) PQftype(result, i));
Tcl_AppendElement(interp, nameBuffer);
sprintf(nameBuffer, "%ld", (long) PQfsize(result, i));
Tcl_AppendElement(interp, nameBuffer);
/* end the sublist */
Tcl_AppendResult(interp, "}", 0);
}
return TCL_OK;
}
else if (strcmp(opt, "-numAttrs") == 0) {
sprintf(interp->result, "%d", PQnfields(result));
return TCL_OK;
}
else {
Tcl_AppendResult(interp, "Invalid option",0);
goto Pg_result_errReturn;
@@ -649,9 +653,9 @@ Pg_result(ClientData cData, Tcl_Interp *interp, int argc, char* argv[])
"\t-assign arrayVarName\n",
"\t-assignbyidx arrayVarName\n",
"\t-numTuples\n",
"\t-numAttrs\n"
"\t-attributes\n"
"\t-lAttributes\n"
"\t-numAttrs\n"
"\t-getTuple tupleNumber\n",
"\t-tupleArray tupleNumber arrayVarName\n",
"\t-clear\n",

View File

@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.11 1998/06/16 04:10:17 momjian Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.12 1998/08/17 03:50:26 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -43,7 +43,10 @@ static int PgEndCopy(Pg_ConnectionId *connid, int *errorCodePtr)
}
/*
* Called when reading data (via gets) for a copy <rel> to stdout
* Called when reading data (via gets) for a copy <rel> to stdout.
*
* NOTE: this routine knows way more than it ought to about libpq's
* internal buffering mechanisms.
*/
int PgInputProc(DRIVER_INPUT_PROTO)
{
@@ -62,10 +65,10 @@ int PgInputProc(DRIVER_INPUT_PROTO)
}
/* Try to load any newly arrived data */
errno = 0;
if (pqReadData(conn) < 0) {
*errorCodePtr = errno ? errno : EIO;
conn->errorMessage[0] = '\0';
PQconsumeInput(conn);
if (conn->errorMessage[0]) {
*errorCodePtr = EIO;
return -1;
}
@@ -80,8 +83,8 @@ int PgInputProc(DRIVER_INPUT_PROTO)
conn->inCursor = conn->inStart;
avail = bufSize;
while (avail > 0 &&
pqGetc(&c, conn) == 0) {
while (avail > 0 && conn->inCursor < conn->inEnd) {
c = conn->inBuffer[conn->inCursor++];
*buf++ = c;
--avail;
if (c == '\n') {
@@ -130,10 +133,12 @@ int PgOutputProc(DRIVER_OUTPUT_PROTO)
return -1;
}
errno = 0;
conn->errorMessage[0] = '\0';
if (pqPutnchar(buf, bufSize, conn)) {
*errorCodePtr = errno ? errno : EIO;
PQputnbytes(conn, buf, bufSize);
if (conn->errorMessage[0]) {
*errorCodePtr = EIO;
return -1;
}
@@ -141,7 +146,6 @@ int PgOutputProc(DRIVER_OUTPUT_PROTO)
* in a single operation; maybe not such a good assumption?
*/
if (bufSize >= 3 && strncmp(&buf[bufSize-3], "\\.\n", 3) == 0) {
(void) pqFlush(conn);
if (PgEndCopy(connid, errorCodePtr) == -1)
return -1;
}
@@ -423,7 +427,7 @@ PgGetConnByResultId(Tcl_Interp *interp, char *resid_c)
*mark = '\0';
conn_chan = Tcl_GetChannel(interp, resid_c, 0);
*mark = '.';
if(conn_chan && Tcl_GetChannelType(conn_chan) != &Pg_ConnType) {
if(conn_chan && Tcl_GetChannelType(conn_chan) == &Pg_ConnType) {
Tcl_SetResult(interp, Tcl_GetChannelName(conn_chan), TCL_VOLATILE);
return TCL_OK;
}