From c4ffc0d940db620c289aef83e6c80c796ff87096 Mon Sep 17 00:00:00 2001 From: Jason Erickson Date: Mon, 8 Jun 2015 11:37:23 -0600 Subject: [PATCH 1/3] Fix Windows 64bit lobject support for very (>2GB) large objects The type 'long' with Windows Visual C is 32bits in size for both 32bit and 64bit platforms. Changed type of variables that could be > 2GB from long to Py_ssize_t. --- psycopg/lobject.h | 4 ++-- psycopg/lobject_int.c | 22 +++++++++++----------- psycopg/lobject_type.c | 20 +++++++++++--------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/psycopg/lobject.h b/psycopg/lobject.h index b9c8c3d8..73cf6192 100644 --- a/psycopg/lobject.h +++ b/psycopg/lobject.h @@ -60,8 +60,8 @@ RAISES_NEG HIDDEN int lobject_export(lobjectObject *self, const char *filename); RAISES_NEG HIDDEN Py_ssize_t lobject_read(lobjectObject *self, char *buf, size_t len); RAISES_NEG HIDDEN Py_ssize_t lobject_write(lobjectObject *self, const char *buf, size_t len); -RAISES_NEG HIDDEN long lobject_seek(lobjectObject *self, long pos, int whence); -RAISES_NEG HIDDEN long lobject_tell(lobjectObject *self); +RAISES_NEG HIDDEN Py_ssize_t lobject_seek(lobjectObject *self, Py_ssize_t pos, int whence); +RAISES_NEG HIDDEN Py_ssize_t lobject_tell(lobjectObject *self); RAISES_NEG HIDDEN int lobject_truncate(lobjectObject *self, size_t len); RAISES_NEG HIDDEN int lobject_close(lobjectObject *self); diff --git a/psycopg/lobject_int.c b/psycopg/lobject_int.c index 6b55d42b..165af6c9 100644 --- a/psycopg/lobject_int.c +++ b/psycopg/lobject_int.c @@ -376,12 +376,12 @@ lobject_read(lobjectObject *self, char *buf, size_t len) /* lobject_seek - move the current position in the lo */ -RAISES_NEG long -lobject_seek(lobjectObject *self, long pos, int whence) +RAISES_NEG Py_ssize_t +lobject_seek(lobjectObject *self, Py_ssize_t pos, int whence) { PGresult *pgres = NULL; char *error = NULL; - long where; + Py_ssize_t where; Dprintf("lobject_seek: fd = %d, pos = %ld, whence = %d", self->fd, pos, whence); @@ -391,12 +391,12 @@ lobject_seek(lobjectObject *self, long pos, int whence) #ifdef HAVE_LO64 if (self->conn->server_version < 90300) { - where = (long)lo_lseek(self->conn->pgconn, self->fd, (int)pos, whence); + where = (Py_ssize_t)lo_lseek(self->conn->pgconn, self->fd, (int)pos, whence); } else { - where = lo_lseek64(self->conn->pgconn, self->fd, pos, whence); + where = (Py_ssize_t)lo_lseek64(self->conn->pgconn, self->fd, pos, whence); } #else - where = (long)lo_lseek(self->conn->pgconn, self->fd, (int)pos, whence); + where = (Py_ssize_t)lo_lseek(self->conn->pgconn, self->fd, (int)pos, whence); #endif Dprintf("lobject_seek: where = %ld", where); if (where < 0) @@ -412,12 +412,12 @@ lobject_seek(lobjectObject *self, long pos, int whence) /* lobject_tell - tell the current position in the lo */ -RAISES_NEG long +RAISES_NEG Py_ssize_t lobject_tell(lobjectObject *self) { PGresult *pgres = NULL; char *error = NULL; - long where; + Py_ssize_t where; Dprintf("lobject_tell: fd = %d", self->fd); @@ -426,12 +426,12 @@ lobject_tell(lobjectObject *self) #ifdef HAVE_LO64 if (self->conn->server_version < 90300) { - where = (long)lo_tell(self->conn->pgconn, self->fd); + where = (Py_ssize_t)lo_tell(self->conn->pgconn, self->fd); } else { - where = lo_tell64(self->conn->pgconn, self->fd); + where = (Py_ssize_t)lo_tell64(self->conn->pgconn, self->fd); } #else - where = (long)lo_tell(self->conn->pgconn, self->fd); + where = (Py_ssize_t)lo_tell(self->conn->pgconn, self->fd); #endif Dprintf("lobject_tell: where = %ld", where); if (where < 0) diff --git a/psycopg/lobject_type.c b/psycopg/lobject_type.c index ec95b5cf..101793f1 100644 --- a/psycopg/lobject_type.c +++ b/psycopg/lobject_type.c @@ -105,7 +105,7 @@ psyco_lobj_write(lobjectObject *self, PyObject *args) goto exit; } - rv = PyInt_FromLong((long)res); + rv = PyInt_FromSsize_t((Py_ssize_t)res); exit: Py_XDECREF(data); @@ -121,7 +121,7 @@ static PyObject * psyco_lobj_read(lobjectObject *self, PyObject *args) { PyObject *res; - long where, end; + Py_ssize_t where, end; Py_ssize_t size = -1; char *buffer; @@ -165,10 +165,10 @@ psyco_lobj_read(lobjectObject *self, PyObject *args) static PyObject * psyco_lobj_seek(lobjectObject *self, PyObject *args) { - long offset, pos=0; + Py_ssize_t offset, pos=0; int whence=0; - if (!PyArg_ParseTuple(args, "l|i", &offset, &whence)) + if (!PyArg_ParseTuple(args, "n|i", &offset, &whence)) return NULL; EXC_IF_LOBJ_CLOSED(self); @@ -197,7 +197,7 @@ psyco_lobj_seek(lobjectObject *self, PyObject *args) if ((pos = lobject_seek(self, offset, whence)) < 0) return NULL; - return PyLong_FromLong(pos); + return PyLong_FromSsize_t(pos); } /* tell method - tell current position in the lobject */ @@ -208,7 +208,7 @@ psyco_lobj_seek(lobjectObject *self, PyObject *args) static PyObject * psyco_lobj_tell(lobjectObject *self, PyObject *args) { - long pos; + Py_ssize_t pos; EXC_IF_LOBJ_CLOSED(self); EXC_IF_LOBJ_LEVEL0(self); @@ -217,7 +217,7 @@ psyco_lobj_tell(lobjectObject *self, PyObject *args) if ((pos = lobject_tell(self)) < 0) return NULL; - return PyLong_FromLong(pos); + return PyLong_FromSsize_t(pos); } /* unlink method - unlink (destroy) the lobject */ @@ -274,10 +274,12 @@ psyco_lobj_get_closed(lobjectObject *self, void *closure) static PyObject * psyco_lobj_truncate(lobjectObject *self, PyObject *args) { - long len = 0; + Py_ssize_t len = 0; - if (!PyArg_ParseTuple(args, "|l", &len)) + Dprintf("psyco_lobj_truncate: Enter lobject object at %p", self); + if (!PyArg_ParseTuple(args, "|n", &len)) return NULL; + Dprintf("psyco_lobj_truncate: Parsed Successfully"); EXC_IF_LOBJ_CLOSED(self); EXC_IF_LOBJ_LEVEL0(self); From 72c7374d8ea8d219c22967332d91996aa399afcb Mon Sep 17 00:00:00 2001 From: Jason Erickson Date: Mon, 8 Jun 2015 14:05:05 -0600 Subject: [PATCH 2/3] Removed added Dprintf statements Removed extra Dprintf statements added to trouble large objects --- psycopg/lobject_type.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/psycopg/lobject_type.c b/psycopg/lobject_type.c index 101793f1..482653ec 100644 --- a/psycopg/lobject_type.c +++ b/psycopg/lobject_type.c @@ -276,10 +276,8 @@ psyco_lobj_truncate(lobjectObject *self, PyObject *args) { Py_ssize_t len = 0; - Dprintf("psyco_lobj_truncate: Enter lobject object at %p", self); if (!PyArg_ParseTuple(args, "|n", &len)) return NULL; - Dprintf("psyco_lobj_truncate: Parsed Successfully"); EXC_IF_LOBJ_CLOSED(self); EXC_IF_LOBJ_LEVEL0(self); From 9021c90c07cc3a1c5242034888b6a945a65f0ddd Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sun, 14 Jun 2015 18:33:22 +0100 Subject: [PATCH 3/3] Fixed compiler warnings about Py_ssize_t printf format --- psycopg/lobject_type.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/psycopg/lobject_type.c b/psycopg/lobject_type.c index 482653ec..973ebe76 100644 --- a/psycopg/lobject_type.c +++ b/psycopg/lobject_type.c @@ -187,8 +187,8 @@ psyco_lobj_seek(lobjectObject *self, PyObject *args) #else if (offset < INT_MIN || offset > INT_MAX) { PyErr_Format(InterfaceError, - "offset out of range (%ld): this psycopg version was not built " - "with lobject 64 API support", + "offset out of range (" FORMAT_CODE_PY_SSIZE_T "): " + "this psycopg version was not built with lobject 64 API support", offset); return NULL; } @@ -286,16 +286,16 @@ psyco_lobj_truncate(lobjectObject *self, PyObject *args) #ifdef HAVE_LO64 if (len > INT_MAX && self->conn->server_version < 90300) { PyErr_Format(NotSupportedError, - "len out of range (%ld): server version %d " - "does not support the lobject 64 API", + "len out of range (" FORMAT_CODE_PY_SSIZE_T "): " + "server version %d does not support the lobject 64 API", len, self->conn->server_version); return NULL; } #else if (len > INT_MAX) { PyErr_Format(InterfaceError, - "len out of range (%ld): this psycopg version was not built " - "with lobject 64 API support", + "len out of range (" FORMAT_CODE_PY_SSIZE_T "): " + "this psycopg version was not built with lobject 64 API support", len); return NULL; }