From dave@bodenstab.org Thu Nov 21 22:17:30 2002 Date: Thu, 21 Nov 2002 16:17:30 -0600 (CST) From: Dave Bodenstab dave@bodenstab.org Subject: [Pgtcl-hackers] pgtcl patch for your consideration
Hello,

A couple of years ago I was trying to use large objects with the
Tcl interface.  I recall that I had to insert debugging code to
try to figure out how things worked at that time.  Honestly, I don't
remember if the attached patch fixed a problem that I actually saw
or was a preemptive fix in case lo_read/write returned short
counts. 

Anyway, I've had the attached patch applied against pgtcl in
postgressql v7.1.3, but I lost interest in my project with large
objects and haven't looked at it for a long time.

The key question is 'does lo_read/write return short counts and/or
error (-1) returns?'  If they do not, then this patch is irrelevant.
If they do, then I think you should consider this patch or something like it.

Sorry, but I cannot test your version of pgtcl with this patch
since I don't have time to upgrade from postgressql 7.1.3, and the
new pgtcl uses a function introduced in a later version.

Use this anyway you want.

Dave Bodenstab


Patch against 1.4b3 :

--- generic/pgtclCmds.c.orig	Fri Nov 15 18:58:47 2002
+++ generic/pgtclCmds.c	Thu Nov 21 15:56:54 2002
@@ -1534,6 +1534,14 @@
 	buf = ckalloc(len + 1);
 
 	nbytes = lo_read(conn, fd, buf, len);
+
+	if (nbytes < 0)
+	{
+		Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
+		rc = TCL_ERROR;
+	}
+	else
+	{
 	bufObj = Tcl_NewStringObj(buf, nbytes);
 
 	if (Tcl_ObjSetVar2(interp, bufVar, NULL, bufObj,
@@ -1541,6 +1549,7 @@
 		rc = TCL_ERROR;
 	else
 		Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
+	}
 
 	ckfree(buf);
 	return rc;
@@ -1562,6 +1571,7 @@
 	char	   *buf;
 	int			fd;
 	int			nbytes = 0;
+	int			nwritten;
 	int			len;
 
 	if (objc != 5)
@@ -1592,8 +1602,17 @@
 		return TCL_OK;
 	}
 
-	nbytes = lo_write(conn, fd, buf, len);
+	nwritten = 0;
+	while (len - nwritten > 0) {
+		nbytes = lo_write(conn, fd, buf + nwritten, len - nwritten);
+		if (nbytes < 0 )
+		{
 	Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
+			return TCL_ERROR;
+		}
+		nwritten += nbytes;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(nwritten));
 	return TCL_OK;
 }
 


From dave at bodenstab.org Thu Nov 21 22:17:30 2002 From: dave at bodenstab.org (Dave Bodenstab) Date: Thu, 21 Nov 2002 16:17:30 -0600 (CST) Subject: [Pgtcl-hackers] pgtcl patch for your consideration Message-ID: <200211212217.gALMHUT21611@base486.home.org> Hello, A couple of years ago I was trying to use large objects with the Tcl interface. I recall that I had to insert debugging code to try to figure out how things worked at that time. Honestly, I don't remember if the attached patch fixed a problem that I actually saw or was a preemptive fix in case lo_read/write returned short counts. Anyway, I've had the attached patch applied against pgtcl in postgressql v7.1.3, but I lost interest in my project with large objects and haven't looked at it for a long time. The key question is 'does lo_read/write return short counts and/or error (-1) returns?' If they do not, then this patch is irrelevant. If they do, then I think you should consider this patch or something like it. Sorry, but I cannot test your version of pgtcl with this patch since I don't have time to upgrade from postgressql 7.1.3, and the new pgtcl uses a function introduced in a later version. Use this anyway you want. Dave Bodenstab Patch against 1.4b3 : --- generic/pgtclCmds.c.orig Fri Nov 15 18:58:47 2002 +++ generic/pgtclCmds.c Thu Nov 21 15:56:54 2002 @@ -1534,6 +1534,14 @@ buf = ckalloc(len + 1); nbytes = lo_read(conn, fd, buf, len); + + if (nbytes < 0) + { + Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes)); + rc = TCL_ERROR; + } + else + { bufObj = Tcl_NewStringObj(buf, nbytes); if (Tcl_ObjSetVar2(interp, bufVar, NULL, bufObj, @@ -1541,6 +1549,7 @@ rc = TCL_ERROR; else Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes)); + } ckfree(buf); return rc; @@ -1562,6 +1571,7 @@ char *buf; int fd; int nbytes = 0; + int nwritten; int len; if (objc != 5) @@ -1592,8 +1602,17 @@ return TCL_OK; } - nbytes = lo_write(conn, fd, buf, len); + nwritten = 0; + while (len - nwritten > 0) { + nbytes = lo_write(conn, fd, buf + nwritten, len - nwritten); + if (nbytes < 0 ) + { Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes)); + return TCL_ERROR; + } + nwritten += nbytes; + } + Tcl_SetObjResult(interp, Tcl_NewIntObj(nwritten)); return TCL_OK; }