libpq(win32) s/errno/WSAGetLastError()/

Started by Sergey Chumakovalmost 25 years ago3 messagespatches
Jump to latest
#1Sergey Chumakov
yas@cit.org.by

Your name : Sergey Chumakov
Your email address : yas@cit.org.by

System Configuration
---------------------
Architecture (example: Intel Pentium) : Intel Pentium

Operating System (example: Linux 2.0.26 ELF) : Windows 2000 SP2

PostgreSQL version (example: PostgreSQL-7.1.3): PostgreSQL-7.1.3

Compiler used (example: gcc 2.95.2) : MSVS6 SP5 (Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86)

Please enter a FULL description of your problem:
------------------------------------------------

libpq PQexec failed with large query (sizeof(Query) > 8192).

Please describe a way to repeat the problem. Please try to provide a
concise reproducible example, if at all possible:
----------------------------------------------------------------------

// SQL: create table test(f1 text); insert into test values(null);

#include <stdlib.h>
#include <string.h>
#include <libpq-fe.h>

int main(int argc, char* argv[])
{
PGconn *conn = NULL;
PGresult *res = NULL;
char *szQ = NULL;

PQconninfoOption* opt = PQconndefaults();

conn = PQsetdbLogin("localhost", NULL, NULL, NULL, "template1", "postgres", NULL);

szQ = (char*)malloc(32000);
memset(szQ, 'A', 64001);
memcpy(szQ, "update test set f1='", strlen("update test set f1='"));
szQ[63998] = '\'';
szQ[63999] = '\0';

if( PQstatus(conn) == CONNECTION_BAD )
{
printf("%s", PQerrorMessage(conn));
goto end_work;
}

res = PQexec(conn, szQ);
if( !res || PQresultStatus(res) != PGRES_COMMAND_OK )
{
printf("%s", PQerrorMessage(conn));
goto end_work;
}

end_work:
if( res )
PQclear(res);
if( conn )
PQfinish(conn);
free(szQ);

return 0;
}

If you know how this problem might be fixed, list the solution below:
---------------------------------------------------------------------

Small patch for socket error detection/processing

diff -rcN postgresql-7.1.3.orig/src/interfaces/libpq/fe-misc.c postgresql-7.1.3/src/interfaces/libpq/fe-misc.c
*** postgresql-7.1.3.orig/src/interfaces/libpq/fe-misc.c	Sun Apr  1 02:13:30 2001
--- postgresql-7.1.3/src/interfaces/libpq/fe-misc.c	Mon Oct 22 17:12:47 2001
***************
*** 328,340 ****
--- 328,347 ----
  	if (select(conn->sock + 1, &input_mask, (fd_set *) NULL, (fd_set *) NULL,
  			   &timeout) < 0)
  	{
+ #ifdef WIN32
+ 	  if (WSAGetLastError() == WSAEINTR)
+ #else
  		if (errno == EINTR)
+ #endif
  			/* Interrupted system call - we'll just try again */
  			goto retry;
  		printfPQExpBuffer(&conn->errorMessage,
  					  "pqReadReady() -- select() failed: errno=%d\n%s\n",
  						  errno, strerror(errno));
+ #ifdef WIN32
+ 		printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
  		return -1;
  	}
***************
*** 362,374 ****
--- 369,388 ----
  	if (select(conn->sock + 1, (fd_set *) NULL, &input_mask, (fd_set *) NULL,
  			   &timeout) < 0)
  	{
+ #ifdef WIN32
+ 	  if (WSAGetLastError() == WSAEINTR)
+ #else
  		if (errno == EINTR)
+ #endif
  			/* Interrupted system call - we'll just try again */
  			goto retry;
  		printfPQExpBuffer(&conn->errorMessage,
  					 "pqWriteReady() -- select() failed: errno=%d\n%s\n",
  						  errno, strerror(errno));
+ #ifdef WIN32
+ 		printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
  		return -1;
  	}
  	return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
***************
*** 441,448 ****
--- 455,475 ----
  					 conn->inBufSize - conn->inEnd, 0);
  	if (nread < 0)
  	{
+ #ifdef WIN32
+ 	  int wserrno = WSAGetLastError();
+ 
+ 	  if (wserrno == WSAEINTR)
+ #else
  		if (errno == EINTR)
+ #endif
  			goto tryAgain;
+ #ifdef WIN32
+ 	  if (wserrno == WSAEWOULDBLOCK)
+ 	    return someread;
+ 
+ 	  if (wserrno == WSAECONNRESET)
+ 	    goto definitelyFailed;
+ #else
  		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
  #ifdef EAGAIN
  		if (errno == EAGAIN)
***************
*** 457,469 ****
  		if (errno == ECONNRESET)
  			goto definitelyFailed;
  #endif
  		printfPQExpBuffer(&conn->errorMessage,
  						"pqReadData() --  read() failed: errno=%d\n%s\n",
  						  errno, strerror(errno));
  		return -1;
  	}
  	if (nread > 0)
! 	{
  		conn->inEnd += nread;
  		/*
--- 484,500 ----
  		if (errno == ECONNRESET)
  			goto definitelyFailed;
  #endif
+ #endif /* WIN32 */
  		printfPQExpBuffer(&conn->errorMessage,
  						"pqReadData() --  read() failed: errno=%d\n%s\n",
  						  errno, strerror(errno));
+ #ifdef WIN32
+ 		printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
  		return -1;
  	}
  	if (nread > 0)
! 	  {
  		conn->inEnd += nread;
  		/*
***************
*** 527,534 ****
--- 558,578 ----
  					 conn->inBufSize - conn->inEnd, 0);
  	if (nread < 0)
  	{
+ #ifdef WIN32
+ 	  int wserrno = WSAGetLastError();
+ 
+ 	  if (wserrno == WSAEINTR)
+ #else
  		if (errno == EINTR)
+ #endif
  			goto tryAgain2;
+ #ifdef WIN32
+ 	  if (wserrno == WSAEWOULDBLOCK)
+ 	    return someread;
+ 
+ 	  if (wserrno == WSAECONNRESET)
+ 	    goto definitelyFailed;
+ #else
  		/* Some systems return EAGAIN/EWOULDBLOCK for no data */
  #ifdef EAGAIN
  		if (errno == EAGAIN)
***************
*** 543,556 ****
  		if (errno == ECONNRESET)
  			goto definitelyFailed;
  #endif
  		printfPQExpBuffer(&conn->errorMessage,
  						"pqReadData() --  read() failed: errno=%d\n%s\n",
  						  errno, strerror(errno));
  		return -1;
  	}
  	if (nread > 0)
  	{
! 		conn->inEnd += nread;
  		return 1;
  	}
--- 587,604 ----
  		if (errno == ECONNRESET)
  			goto definitelyFailed;
  #endif
+ #endif
  		printfPQExpBuffer(&conn->errorMessage,
  						"pqReadData() --  read() failed: errno=%d\n%s\n",
  						  errno, strerror(errno));
+ #ifdef WIN32
+ 		printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
  		return -1;
  	}
  	if (nread > 0)
  	{
! 	  conn->inEnd += nread;
  		return 1;
  	}
***************
*** 627,632 ****
--- 675,689 ----
  			 * EPIPE or ECONNRESET, assume we've lost the backend
  			 * connection permanently.
  			 */
+ #ifdef WIN32
+ 		  switch (WSAGetLastError())
+ 		    {
+ 		    case WSAEWOULDBLOCK:
+ 		      break;
+ 		    case WSAEINTR:
+ 		      continue;
+ 		    case WSAECONNRESET:
+ #else
  			switch (errno)
  			{
  #ifdef EAGAIN
***************
*** 644,649 ****
--- 701,707 ----
  #ifdef ECONNRESET
  				case ECONNRESET:
  #endif
+ #endif
  					printfPQExpBuffer(&conn->errorMessage,
  									  "pqFlush() -- backend closed the channel unexpectedly.\n"
  									  "\tThis probably means the backend terminated abnormally"
***************
*** 663,668 ****
--- 721,729 ----
  					printfPQExpBuffer(&conn->errorMessage,
  					  "pqFlush() --  couldn't send data: errno=%d\n%s\n",
  									  errno, strerror(errno));
+ #ifdef WIN32
+ 					printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
  					/* We don't assume it's a fatal error... */
  					return EOF;
  			}
***************
*** 745,755 ****
--- 806,823 ----
  		if (select(conn->sock + 1, &input_mask, &output_mask, &except_mask,
  				   (struct timeval *) NULL) < 0)
  		{
+ #ifdef WIN32
+ 		  if (WSAGetLastError() == WSAEINTR)
+ #else
  			if (errno == EINTR)
+ #endif
  				goto retry;
  			printfPQExpBuffer(&conn->errorMessage,
  							  "pqWait() -- select() failed: errno=%d\n%s\n",
  							  errno, strerror(errno));
+ #ifdef WIN32
+ 			printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
  			return EOF;
  		}
  	}
#2Bruce Momjian
bruce@momjian.us
In reply to: Sergey Chumakov (#1)
Re: libpq(win32) s/errno/WSAGetLastError()/

This is all fixed in CVS and will be in 7.2.

---------------------------------------------------------------------------

Your name : Sergey Chumakov
Your email address : yas@cit.org.by

System Configuration
---------------------
Architecture (example: Intel Pentium) : Intel Pentium

Operating System (example: Linux 2.0.26 ELF) : Windows 2000 SP2

PostgreSQL version (example: PostgreSQL-7.1.3): PostgreSQL-7.1.3

Compiler used (example: gcc 2.95.2) : MSVS6 SP5 (Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86)

Please enter a FULL description of your problem:
------------------------------------------------

libpq PQexec failed with large query (sizeof(Query) > 8192).

Please describe a way to repeat the problem. Please try to provide a
concise reproducible example, if at all possible:
----------------------------------------------------------------------

// SQL: create table test(f1 text); insert into test values(null);

#include <stdlib.h>
#include <string.h>
#include <libpq-fe.h>

int main(int argc, char* argv[])
{
PGconn *conn = NULL;
PGresult *res = NULL;
char *szQ = NULL;

PQconninfoOption* opt = PQconndefaults();

conn = PQsetdbLogin("localhost", NULL, NULL, NULL, "template1", "postgres", NULL);

szQ = (char*)malloc(32000);
memset(szQ, 'A', 64001);
memcpy(szQ, "update test set f1='", strlen("update test set f1='"));
szQ[63998] = '\'';
szQ[63999] = '\0';

if( PQstatus(conn) == CONNECTION_BAD )
{
printf("%s", PQerrorMessage(conn));
goto end_work;
}

res = PQexec(conn, szQ);
if( !res || PQresultStatus(res) != PGRES_COMMAND_OK )
{
printf("%s", PQerrorMessage(conn));
goto end_work;
}

end_work:
if( res )
PQclear(res);
if( conn )
PQfinish(conn);
free(szQ);

return 0;
}

If you know how this problem might be fixed, list the solution below:
---------------------------------------------------------------------

Small patch for socket error detection/processing

diff -rcN postgresql-7.1.3.orig/src/interfaces/libpq/fe-misc.c postgresql-7.1.3/src/interfaces/libpq/fe-misc.c
*** postgresql-7.1.3.orig/src/interfaces/libpq/fe-misc.c	Sun Apr  1 02:13:30 2001
--- postgresql-7.1.3/src/interfaces/libpq/fe-misc.c	Mon Oct 22 17:12:47 2001
***************
*** 328,340 ****
--- 328,347 ----
if (select(conn->sock + 1, &input_mask, (fd_set *) NULL, (fd_set *) NULL,
&timeout) < 0)
{
+ #ifdef WIN32
+ 	  if (WSAGetLastError() == WSAEINTR)
+ #else
if (errno == EINTR)
+ #endif
/* Interrupted system call - we'll just try again */
goto retry;
printfPQExpBuffer(&conn->errorMessage,
"pqReadReady() -- select() failed: errno=%d\n%s\n",
errno, strerror(errno));
+ #ifdef WIN32
+ 		printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
return -1;
}
***************
*** 362,374 ****
--- 369,388 ----
if (select(conn->sock + 1, (fd_set *) NULL, &input_mask, (fd_set *) NULL,
&timeout) < 0)
{
+ #ifdef WIN32
+ 	  if (WSAGetLastError() == WSAEINTR)
+ #else
if (errno == EINTR)
+ #endif
/* Interrupted system call - we'll just try again */
goto retry;
printfPQExpBuffer(&conn->errorMessage,
"pqWriteReady() -- select() failed: errno=%d\n%s\n",
errno, strerror(errno));
+ #ifdef WIN32
+ 		printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
return -1;
}
return FD_ISSET(conn->sock, &input_mask) ? 1 : 0;
***************
*** 441,448 ****
--- 455,475 ----
conn->inBufSize - conn->inEnd, 0);
if (nread < 0)
{
+ #ifdef WIN32
+ 	  int wserrno = WSAGetLastError();
+ 
+ 	  if (wserrno == WSAEINTR)
+ #else
if (errno == EINTR)
+ #endif
goto tryAgain;
+ #ifdef WIN32
+ 	  if (wserrno == WSAEWOULDBLOCK)
+ 	    return someread;
+ 
+ 	  if (wserrno == WSAECONNRESET)
+ 	    goto definitelyFailed;
+ #else
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
#ifdef EAGAIN
if (errno == EAGAIN)
***************
*** 457,469 ****
if (errno == ECONNRESET)
goto definitelyFailed;
#endif
printfPQExpBuffer(&conn->errorMessage,
"pqReadData() --  read() failed: errno=%d\n%s\n",
errno, strerror(errno));
return -1;
}
if (nread > 0)
! 	{
conn->inEnd += nread;
/*
--- 484,500 ----
if (errno == ECONNRESET)
goto definitelyFailed;
#endif
+ #endif /* WIN32 */
printfPQExpBuffer(&conn->errorMessage,
"pqReadData() --  read() failed: errno=%d\n%s\n",
errno, strerror(errno));
+ #ifdef WIN32
+ 		printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
return -1;
}
if (nread > 0)
! 	  {
conn->inEnd += nread;
/*
***************
*** 527,534 ****
--- 558,578 ----
conn->inBufSize - conn->inEnd, 0);
if (nread < 0)
{
+ #ifdef WIN32
+ 	  int wserrno = WSAGetLastError();
+ 
+ 	  if (wserrno == WSAEINTR)
+ #else
if (errno == EINTR)
+ #endif
goto tryAgain2;
+ #ifdef WIN32
+ 	  if (wserrno == WSAEWOULDBLOCK)
+ 	    return someread;
+ 
+ 	  if (wserrno == WSAECONNRESET)
+ 	    goto definitelyFailed;
+ #else
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
#ifdef EAGAIN
if (errno == EAGAIN)
***************
*** 543,556 ****
if (errno == ECONNRESET)
goto definitelyFailed;
#endif
printfPQExpBuffer(&conn->errorMessage,
"pqReadData() --  read() failed: errno=%d\n%s\n",
errno, strerror(errno));
return -1;
}
if (nread > 0)
{
! 		conn->inEnd += nread;
return 1;
}
--- 587,604 ----
if (errno == ECONNRESET)
goto definitelyFailed;
#endif
+ #endif
printfPQExpBuffer(&conn->errorMessage,
"pqReadData() --  read() failed: errno=%d\n%s\n",
errno, strerror(errno));
+ #ifdef WIN32
+ 		printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
return -1;
}
if (nread > 0)
{
! 	  conn->inEnd += nread;
return 1;
}
***************
*** 627,632 ****
--- 675,689 ----
* EPIPE or ECONNRESET, assume we've lost the backend
* connection permanently.
*/
+ #ifdef WIN32
+ 		  switch (WSAGetLastError())
+ 		    {
+ 		    case WSAEWOULDBLOCK:
+ 		      break;
+ 		    case WSAEINTR:
+ 		      continue;
+ 		    case WSAECONNRESET:
+ #else
switch (errno)
{
#ifdef EAGAIN
***************
*** 644,649 ****
--- 701,707 ----
#ifdef ECONNRESET
case ECONNRESET:
#endif
+ #endif
printfPQExpBuffer(&conn->errorMessage,
"pqFlush() -- backend closed the channel unexpectedly.\n"
"\tThis probably means the backend terminated abnormally"
***************
*** 663,668 ****
--- 721,729 ----
printfPQExpBuffer(&conn->errorMessage,
"pqFlush() --  couldn't send data: errno=%d\n%s\n",
errno, strerror(errno));
+ #ifdef WIN32
+ 					printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
/* We don't assume it's a fatal error... */
return EOF;
}
***************
*** 745,755 ****
--- 806,823 ----
if (select(conn->sock + 1, &input_mask, &output_mask, &except_mask,
(struct timeval *) NULL) < 0)
{
+ #ifdef WIN32
+ 		  if (WSAGetLastError() == WSAEINTR)
+ #else
if (errno == EINTR)
+ #endif
goto retry;
printfPQExpBuffer(&conn->errorMessage,
"pqWait() -- select() failed: errno=%d\n%s\n",
errno, strerror(errno));
+ #ifdef WIN32
+ 			printf("Winsock error: %i\n", WSAGetLastError());
+ #endif
return EOF;
}
}

---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majordomo@postgresql.org so that your
message can get through to the mailing list cleanly

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Sergey Chumakov (#1)
Re: libpq(win32) s/errno/WSAGetLastError()/

Sergey Chumakov <yas@cit.org.by> writes:

Small patch for socket error detection/processing

I think this has already been addressed. Would you look at current
sources (grab a nightly snapshot, or pull from the CVS server) and
see if it works for you?

regards, tom lane