I broke it, I'm guilty :-(.  Here's the fix.

In view of recent discussions about eliminating the fixed limit
on tuple sizes, a better long-term solution would be to increase
the width of field size values from 2 bytes to 4 in the FE/BE
protocol.  I suspect we will end up doing that someday, so maybe
we should bite the bullet and do it now as part of the "2.0" FE/BE
protocol revision.  On the other hand, we did promise a few weeks ago
that we were done changing the FE/BE protocol for 6.4.  Comments?

			regards, tom lane


*** src/interfaces/libpq/fe-exec.c.orig	Wed Sep  9 22:01:38 1998
--- src/interfaces/libpq/fe-exec.c	Wed Sep  9 22:45:53 1998
***************
*** 541,546 ****
--- 541,556 ----
  			PQclear(result);
  			return EOF;
  		}
+ 		/*
+ 		 * Since pqGetInt treats 2-byte integers as unsigned, we need to
+ 		 * coerce the special value "-1" to signed form.  (-1 is sent for
+ 		 * variable-length fields.)  Formerly, libpq effectively did a
+ 		 * sign-extension on the 2-byte value by storing it in a signed short.
+ 		 * Now we only coerce the single value 65535 == -1; values
+ 		 * 32768..65534 are taken as valid field lengths.
+ 		 */
+ 		if (typlen == 0xFFFF)
+ 			typlen = -1;
  		result->attDescs[i].name = strdup(typName);
  		result->attDescs[i].typid = typid;
  		result->attDescs[i].typlen = typlen;
***************
*** 1488,1494 ****
  	if (strncmp(res->cmdStatus, "INSERT ", 7) != 0)
  		return "";
  
! 	/*
  	 * The cmdStatus string looks like
  	 *     INSERT oid count\0
  	 * In order to be able to return an ordinary C string without
--- 1498,1504 ----
  	if (strncmp(res->cmdStatus, "INSERT ", 7) != 0)
  		return "";
  
! 	/*----------
  	 * The cmdStatus string looks like
  	 *     INSERT oid count\0
  	 * In order to be able to return an ordinary C string without
***************
*** 1498,1503 ****
--- 1508,1514 ----
  	 *     INSERT oid count\0oid\0
  	 *                       ^ our return value points here
  	 * Pretty klugy eh?  This routine should've just returned an Oid value.
+ 	 *----------
  	 */
  
  	slen = strlen(res->cmdStatus);

Wed, 09 Sep 1998 23:02:36 -0400
Tom Lane <tgl@sss.pgh.pa.us>
fix for libpq choking on varlen fields
patch applied.


> I broke it, I'm guilty :-(.  Here's the fix.
> 
> In view of recent discussions about eliminating the fixed limit
> on tuple sizes, a better long-term solution would be to increase
> the width of field size values from 2 bytes to 4 in the FE/BE
> protocol.  I suspect we will end up doing that someday, so maybe
> we should bite the bullet and do it now as part of the "2.0" FE/BE
> protocol revision.  On the other hand, we did promise a few weeks ago
> that we were done changing the FE/BE protocol for 6.4.  Comments?
> 
> 			regards, tom lane
> 
> 
> *** src/interfaces/libpq/fe-exec.c.orig	Wed Sep  9 22:01:38 1998
> --- src/interfaces/libpq/fe-exec.c	Wed Sep  9 22:45:53 1998
> ***************
> *** 541,546 ****
> --- 541,556 ----
>   			PQclear(result);
>   			return EOF;
>   		}
> + 		/*
> + 		 * Since pqGetInt treats 2-byte integers as unsigned, we need to
> + 		 * coerce the special value "-1" to signed form.  (-1 is sent for
> + 		 * variable-length fields.)  Formerly, libpq effectively did a
> + 		 * sign-extension on the 2-byte value by storing it in a signed short.
> + 		 * Now we only coerce the single value 65535 == -1; values
> + 		 * 32768..65534 are taken as valid field lengths.
> + 		 */
> + 		if (typlen == 0xFFFF)
> + 			typlen = -1;
>   		result->attDescs[i].name = strdup(typName);
>   		result->attDescs[i].typid = typid;
>   		result->attDescs[i].typlen = typlen;
> ***************
> *** 1488,1494 ****
>   	if (strncmp(res->cmdStatus, "INSERT ", 7) != 0)
>   		return "";
>   
> ! 	/*
>   	 * The cmdStatus string looks like
>   	 *     INSERT oid count\0
>   	 * In order to be able to return an ordinary C string without
> --- 1498,1504 ----
>   	if (strncmp(res->cmdStatus, "INSERT ", 7) != 0)
>   		return "";
>   
> ! 	/*----------
>   	 * The cmdStatus string looks like
>   	 *     INSERT oid count\0
>   	 * In order to be able to return an ordinary C string without
> ***************
> *** 1498,1503 ****
> --- 1508,1514 ----
>   	 *     INSERT oid count\0oid\0
>   	 *                       ^ our return value points here
>   	 * Pretty klugy eh?  This routine should've just returned an Oid value.
> + 	 *----------
>   	 */
>   
>   	slen = strlen(res->cmdStatus);
> 
> 


-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist@candle.pha.pa.us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)

Thu, 10 Sep 1998 11:09:38 -0400 (EDT)
Bruce Momjian <maillist@candle.pha.pa.us>
Re: [HACKERS] fix for libpq choking on varlen fields