|
|
|
@ -7,7 +7,7 @@ |
|
|
|
|
* |
|
|
|
|
* |
|
|
|
|
* IDENTIFICATION |
|
|
|
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.13 1996/08/06 16:16:46 scrappy Exp $ |
|
|
|
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.14 1996/08/10 00:22:48 scrappy Exp $ |
|
|
|
|
* |
|
|
|
|
*------------------------------------------------------------------------- |
|
|
|
|
*/ |
|
|
|
@ -131,7 +131,7 @@ getTuple(PGconn *conn, PGresult* result, int binary) |
|
|
|
|
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; |
|
|
|
|
FILE *pfdebug = conn->Pfdebug; |
|
|
|
|
|
|
|
|
|
PGresAttValue* tup; |
|
|
|
|
|
|
|
|
@ -145,7 +145,7 @@ getTuple(PGconn *conn, PGresult* result, int binary) |
|
|
|
|
if ( (nfields % BYTELEN) > 0) |
|
|
|
|
nbytes++; |
|
|
|
|
|
|
|
|
|
if (pqGetnchar(bitmap, nbytes, pfin, Pfdebug) == 1){ |
|
|
|
|
if (pqGetnchar(bitmap, nbytes, pfin, pfdebug) == 1){ |
|
|
|
|
sprintf(conn->errorMessage, |
|
|
|
|
"Error reading null-values bitmap from tuple data stream\n"); |
|
|
|
|
return NULL; |
|
|
|
@ -164,7 +164,7 @@ getTuple(PGconn *conn, PGresult* result, int binary) |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
/* get the value length (the first four bytes are for length) */ |
|
|
|
|
pqGetInt(&vlen, VARHDRSZ, pfin, Pfdebug); |
|
|
|
|
pqGetInt(&vlen, VARHDRSZ, pfin, pfdebug); |
|
|
|
|
if (binary == 0) { |
|
|
|
|
vlen = vlen - VARHDRSZ; |
|
|
|
|
} |
|
|
|
@ -174,7 +174,7 @@ getTuple(PGconn *conn, PGresult* result, int binary) |
|
|
|
|
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 */ |
|
|
|
@ -241,7 +241,7 @@ makePGresult(PGconn* conn, char* pname) |
|
|
|
|
PGresAttValue* newTup; |
|
|
|
|
|
|
|
|
|
FILE* pfin = conn->Pfin; |
|
|
|
|
FILE* Pfdebug = conn->Pfdebug; |
|
|
|
|
FILE* pfdebug = conn->Pfdebug; |
|
|
|
|
|
|
|
|
|
result = makeEmptyPGresult(conn, PGRES_TUPLES_OK); |
|
|
|
|
|
|
|
|
@ -249,7 +249,7 @@ makePGresult(PGconn* conn, char* pname) |
|
|
|
|
/* id of the stream is 'T' to start with */ |
|
|
|
|
|
|
|
|
|
/* the next two bytes are the number of fields */ |
|
|
|
|
if (pqGetInt(&nfields, 2, pfin, Pfdebug) == 1) { |
|
|
|
|
if (pqGetInt(&nfields, 2, pfin, pfdebug) == 1) { |
|
|
|
|
sprintf(conn->errorMessage, |
|
|
|
|
"could not get the number of fields from the 'T' message\n"); |
|
|
|
|
goto makePGresult_badResponse_return; |
|
|
|
@ -268,9 +268,9 @@ makePGresult(PGconn* conn, char* pname) |
|
|
|
|
int adtid; |
|
|
|
|
int adtsize; |
|
|
|
|
|
|
|
|
|
if ( pqGets(typName, MAX_MESSAGE_LEN, pfin, Pfdebug) || |
|
|
|
|
pqGetInt(&adtid, 4, pfin, Pfdebug) || |
|
|
|
|
pqGetInt(&adtsize, 2, pfin, Pfdebug)) { |
|
|
|
|
if ( pqGets(typName, MAX_MESSAGE_LEN, pfin, pfdebug) || |
|
|
|
|
pqGetInt(&adtid, 4, pfin, pfdebug) || |
|
|
|
|
pqGetInt(&adtsize, 2, pfin, pfdebug)) { |
|
|
|
|
sprintf(conn->errorMessage, |
|
|
|
|
"error reading type information from the 'T' message\n"); |
|
|
|
|
goto makePGresult_badResponse_return; |
|
|
|
@ -281,7 +281,7 @@ makePGresult(PGconn* conn, char* pname) |
|
|
|
|
result->attDescs[i].adtsize = adtsize; /* casting from int to int2 here */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
id = pqGetc(pfin,Pfdebug); |
|
|
|
|
id = pqGetc(pfin,pfdebug); |
|
|
|
|
|
|
|
|
|
/* process the data stream until we're finished */ |
|
|
|
|
while(!done) { |
|
|
|
@ -306,12 +306,12 @@ makePGresult(PGconn* conn, char* pname) |
|
|
|
|
case 'C': /* end of portal tuple 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 the command tag */ |
|
|
|
|
done = 1; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 'E': /* errors */ |
|
|
|
|
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, Pfdebug) == 1) { |
|
|
|
|
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) { |
|
|
|
|
sprintf(conn->errorMessage, |
|
|
|
|
"Error return detected from backend, but error message cannot be read"); |
|
|
|
|
} |
|
|
|
@ -319,7 +319,7 @@ makePGresult(PGconn* conn, char* pname) |
|
|
|
|
return result; |
|
|
|
|
break; |
|
|
|
|
case 'N': /* notices from the backend */ |
|
|
|
|
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, Pfdebug) == 1) { |
|
|
|
|
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 |
|
|
|
@ -370,7 +370,7 @@ PQexec(PGconn* conn, const char* query) |
|
|
|
|
char cmdStatus[MAX_MESSAGE_LEN]; |
|
|
|
|
char pname[MAX_MESSAGE_LEN]; /* portal name */ |
|
|
|
|
PGnotify *newNotify; |
|
|
|
|
FILE *pfin, *pfout, *Pfdebug; |
|
|
|
|
FILE *pfin, *pfout, *pfdebug; |
|
|
|
|
|
|
|
|
|
pname[0]='\0'; |
|
|
|
|
|
|
|
|
@ -380,9 +380,9 @@ PQexec(PGconn* conn, const char* query) |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Pfin = conn->Pfin; |
|
|
|
|
Pfout = conn->Pfout; |
|
|
|
|
Pfdebug = conn->Pfdebug; |
|
|
|
|
pfin = conn->Pfin; |
|
|
|
|
pfout = conn->Pfout; |
|
|
|
|
pfdebug = conn->Pfdebug; |
|
|
|
|
|
|
|
|
|
/*clear the error string */ |
|
|
|
|
conn->errorMessage[0] = '\0'; |
|
|
|
@ -397,7 +397,7 @@ PQexec(PGconn* conn, const char* query) |
|
|
|
|
sprintf(buffer,"Q%s",query); |
|
|
|
|
|
|
|
|
|
/* send the query to the backend; */ |
|
|
|
|
if (pqPuts(buffer,pfout, Pfdebug) == 1) { |
|
|
|
|
if (pqPuts(buffer,pfout, pfdebug) == 1) { |
|
|
|
|
(void) sprintf(conn->errorMessage, |
|
|
|
|
"PQexec() -- while sending query: %s\n-- fprintf to Pfout failed: errno=%d\n%s\n", |
|
|
|
|
query, errno,strerror(errno)); |
|
|
|
@ -412,7 +412,7 @@ PQexec(PGconn* conn, const char* query) |
|
|
|
|
while (1) { |
|
|
|
|
|
|
|
|
|
/* read the result id */ |
|
|
|
|
id = pqGetc(pfin,Pfdebug); |
|
|
|
|
id = pqGetc(pfin,pfdebug); |
|
|
|
|
if (id == EOF) { |
|
|
|
|
/* hmm, no response from the backend-end, that's bad */ |
|
|
|
|
(void) sprintf(conn->errorMessage, |
|
|
|
@ -423,14 +423,14 @@ 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); |
|
|
|
|
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 */ |
|
|
|
|
if (pqGets(cmdStatus, MAX_MESSAGE_LEN, pfin, Pfdebug) == 1) { |
|
|
|
|
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; |
|
|
|
@ -444,10 +444,10 @@ PQexec(PGconn* conn, const char* query) |
|
|
|
|
*/ |
|
|
|
|
clear = 0; |
|
|
|
|
|
|
|
|
|
pqPuts("Q ",pfout,Pfdebug); /* send an empty query */ |
|
|
|
|
pqPuts("Q ",pfout,pfdebug); /* send an empty query */ |
|
|
|
|
while (!clear) |
|
|
|
|
{ |
|
|
|
|
if (pqGets(buffer,ERROR_MSG_LENGTH,pfin,Pfdebug) == 1) |
|
|
|
|
if (pqGets(buffer,ERROR_MSG_LENGTH,pfin,pfdebug) == 1) |
|
|
|
|
clear = 1; |
|
|
|
|
clear = (buffer[0] == 'I'); |
|
|
|
|
} |
|
|
|
@ -457,7 +457,7 @@ PQexec(PGconn* conn, const char* query) |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 'E': /* error return */ |
|
|
|
|
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, Pfdebug) == 1) { |
|
|
|
|
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"); |
|
|
|
|
} |
|
|
|
@ -467,7 +467,7 @@ PQexec(PGconn* conn, const char* query) |
|
|
|
|
/* read the throw away the closing '\0' */ |
|
|
|
|
{ |
|
|
|
|
int c; |
|
|
|
|
if ((c = pqGetc(pfin,Pfdebug)) != '\0') { |
|
|
|
|
if ((c = pqGetc(pfin,pfdebug)) != '\0') { |
|
|
|
|
fprintf(stderr,"error!, unexpected character %c following 'I'\n", c); |
|
|
|
|
} |
|
|
|
|
result = makeEmptyPGresult(conn, PGRES_EMPTY_QUERY); |
|
|
|
@ -475,7 +475,7 @@ PQexec(PGconn* conn, const char* query) |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 'N': /* notices from the backend */ |
|
|
|
|
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, Pfdebug) == 1) { |
|
|
|
|
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; |
|
|
|
@ -484,7 +484,7 @@ PQexec(PGconn* conn, const char* query) |
|
|
|
|
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 the portal name*/ |
|
|
|
|
break; |
|
|
|
|
case 'T': /* actual tuple results: */ |
|
|
|
|
return makePGresult(conn, pname); |
|
|
|
@ -605,21 +605,21 @@ int |
|
|
|
|
PQendcopy(PGconn *conn) |
|
|
|
|
{ |
|
|
|
|
char id; |
|
|
|
|
FILE *pfin, *Pfdebug; |
|
|
|
|
FILE *pfin, *pfdebug; |
|
|
|
|
|
|
|
|
|
if (!conn) return (int)NULL; |
|
|
|
|
|
|
|
|
|
Pfin = conn->Pfin; |
|
|
|
|
Pfdebug = conn->Pfdebug; |
|
|
|
|
pfin = conn->Pfin; |
|
|
|
|
pfdebug = conn->Pfdebug; |
|
|
|
|
|
|
|
|
|
if ( (id = pqGetc(pfin,Pfdebug)) > 0) |
|
|
|
|
if ( (id = pqGetc(pfin,pfdebug)) > 0) |
|
|
|
|
return(0); |
|
|
|
|
switch (id) { |
|
|
|
|
case 'Z': /* backend finished the copy */ |
|
|
|
|
return(1); |
|
|
|
|
case 'E': |
|
|
|
|
case 'N': |
|
|
|
|
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, Pfdebug) == 1) { |
|
|
|
|
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, pfin, pfdebug) == 1) { |
|
|
|
|
sprintf(conn->errorMessage, |
|
|
|
|
"Error return detected from backend, but error message cannot be read"); |
|
|
|
|
} |
|
|
|
@ -1197,37 +1197,37 @@ PQfn(PGconn *conn, |
|
|
|
|
PQArgBlock *args, |
|
|
|
|
int nargs) |
|
|
|
|
{ |
|
|
|
|
FILE *pfin, *pfout, *Pfdebug; |
|
|
|
|
FILE *pfin, *pfout, *pfdebug; |
|
|
|
|
int id; |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
if (!conn) return NULL; |
|
|
|
|
|
|
|
|
|
Pfin = conn->Pfin; |
|
|
|
|
Pfout = conn->Pfout; |
|
|
|
|
Pfdebug = conn->Pfdebug; |
|
|
|
|
pfin = conn->Pfin; |
|
|
|
|
pfout = conn->Pfout; |
|
|
|
|
pfdebug = conn->Pfdebug; |
|
|
|
|
|
|
|
|
|
/* clear the error string */ |
|
|
|
|
conn->errorMessage[0] = '\0'; |
|
|
|
|
|
|
|
|
|
pqPuts("F ",pfout,Pfdebug); /* function */ |
|
|
|
|
pqPutInt(fnid, 4, pfout, Pfdebug); /* function id */ |
|
|
|
|
pqPutInt(nargs, 4, pfout, Pfdebug); /* # of args */ |
|
|
|
|
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); |
|
|
|
|
pqPutInt(args[i].len, 4, pfout, pfdebug); |
|
|
|
|
if (args[i].isint) { |
|
|
|
|
pqPutInt(args[i].u.integer, 4, pfout, Pfdebug); |
|
|
|
|
pqPutInt(args[i].u.integer, 4, pfout, pfdebug); |
|
|
|
|
} else { |
|
|
|
|
pqPutnchar((char *)args[i].u.ptr, args[i].len, pfout, Pfdebug); |
|
|
|
|
pqPutnchar((char *)args[i].u.ptr, args[i].len, pfout, pfdebug); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
pqFlush(pfout, Pfdebug); |
|
|
|
|
pqFlush(pfout, pfdebug); |
|
|
|
|
|
|
|
|
|
id = pqGetc(pfin, Pfdebug); |
|
|
|
|
id = pqGetc(pfin, pfdebug); |
|
|
|
|
if (id != 'V') { |
|
|
|
|
if (id == 'E') { |
|
|
|
|
pqGets(conn->errorMessage,ERROR_MSG_LENGTH,pfin,Pfdebug); |
|
|
|
|
pqGets(conn->errorMessage,ERROR_MSG_LENGTH,pfin,pfdebug); |
|
|
|
|
} else |
|
|
|
|
sprintf(conn->errorMessage, |
|
|
|
|
"PQfn: expected a 'V' from the backend. Got '%c' instead", |
|
|
|
@ -1235,19 +1235,19 @@ PQfn(PGconn *conn, |
|
|
|
|
return makeEmptyPGresult(conn,PGRES_FATAL_ERROR); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
id = pqGetc(pfin, Pfdebug); |
|
|
|
|
id = pqGetc(pfin, pfdebug); |
|
|
|
|
for (;;) { |
|
|
|
|
int c; |
|
|
|
|
switch (id) { |
|
|
|
|
case 'G': /* function returned properly */ |
|
|
|
|
pqGetInt(actual_result_len,4,pfin,Pfdebug); |
|
|
|
|
pqGetInt(actual_result_len,4,pfin,pfdebug); |
|
|
|
|
if (result_is_int) { |
|
|
|
|
pqGetInt(result_buf,4,pfin,Pfdebug); |
|
|
|
|
pqGetInt(result_buf,4,pfin,pfdebug); |
|
|
|
|
} else { |
|
|
|
|
pqGetnchar((char *) result_buf, *actual_result_len, |
|
|
|
|
pfin, Pfdebug); |
|
|
|
|
pfin, pfdebug); |
|
|
|
|
} |
|
|
|
|
c = pqGetc(pfin, Pfdebug); /* get the last '0'*/ |
|
|
|
|
c = pqGetc(pfin, pfdebug); /* get the last '0'*/ |
|
|
|
|
return makeEmptyPGresult(conn,PGRES_COMMAND_OK); |
|
|
|
|
case 'E': |
|
|
|
|
sprintf(conn->errorMessage, |
|
|
|
@ -1255,7 +1255,7 @@ PQfn(PGconn *conn, |
|
|
|
|
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) { |
|
|
|
|
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 |
|
|
|
|