summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--doc/src/extensions.rst10
-rw-r--r--psycopg/column_type.c3
-rw-r--r--psycopg/pqpath.c290
-rw-r--r--setup.cfg5
5 files changed, 158 insertions, 151 deletions
diff --git a/NEWS b/NEWS
index 8ed79c8..1558bea 100644
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,7 @@ Other changes:
- Dropped deprecated `!register_tstz_w_secs()` (was previously a no-op).
- Dropped deprecated `!PersistentConnectionPool`. This pool class was mostly
designed to interact with Zope. Use `!ZPsycopgDA.pool` instead.
+- Dropped `!PSYCOPG_DISPLAY_SIZE` build parameter.
- No longer use 2to3 during installation for Python 2 & 3 compatability. All
source files are now compatible with Python 2 & 3 as is.
- The `!psycopg2.test` package is no longer installed by ``python setup.py
diff --git a/doc/src/extensions.rst b/doc/src/extensions.rst
index 9e99ef1..cc40050 100644
--- a/doc/src/extensions.rst
+++ b/doc/src/extensions.rst
@@ -216,10 +216,12 @@ introspection etc.
.. attribute:: display_size
- The actual length of the column in bytes. Obtaining this value is
- computationally intensive, so it is always `!None` unless the
- :envvar:`PSYCOPG_DISPLAY_SIZE` parameter is set at compile time. See
- also PQgetlength_.
+ Supposed to be the actual length of the column in bytes. Obtaining
+ this value is computationally intensive, so it is always `!None`.
+
+ .. versionchanged:: 2.8
+ It was previously possible to obtain this value using a compiler
+ flag at builtin.
.. attribute:: internal_size
diff --git a/psycopg/column_type.c b/psycopg/column_type.c
index f024a12..1c0f7f9 100644
--- a/psycopg/column_type.c
+++ b/psycopg/column_type.c
@@ -46,8 +46,7 @@ static const char type_code_doc[] =
static const char display_size_doc[] =
"The actual length of the column in bytes.\n\n"
- "Obtaining this value is computationally intensive, so it is always None\n"
- "unless the PSYCOPG_DISPLAY_SIZE parameter is set at compile time.";
+ "Obtaining this value is computationally intensive, so it is always None";
static const char internal_size_doc[] =
"The size in bytes of the column associated to this column on the server.\n\n"
diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c
index 7d085a2..db5968a 100644
--- a/psycopg/pqpath.c
+++ b/psycopg/pqpath.c
@@ -1229,12 +1229,147 @@ pq_get_last_result(connectionObject *conn)
1 - result from backend (possibly data is ready)
*/
+static PyObject *
+_get_cast(cursorObject *curs, PGresult *pgres, int i)
+{
+ /* fill the right cast function by accessing three different dictionaries:
+ - the per-cursor dictionary, if available (can be NULL or None)
+ - the per-connection dictionary (always exists but can be null)
+ - the global dictionary (at module level)
+ if we get no defined cast use the default one */
+ PyObject *type = NULL;
+ PyObject *cast = NULL;
+ PyObject *rv = NULL;
+
+ Oid ftype = PQftype(pgres, i);
+ if (!(type = PyInt_FromLong(ftype))) { goto exit; }
+
+ Dprintf("_pq_fetch_tuples: looking for cast %d:", ftype);
+ if (!(cast = curs_get_cast(curs, type))) { goto exit; }
+
+ /* else if we got binary tuples and if we got a field that
+ is binary use the default cast
+ FIXME: what the hell am I trying to do here? This just can't work..
+ */
+ if (cast == psyco_default_binary_cast && PQbinaryTuples(pgres)) {
+ Dprintf("_pq_fetch_tuples: Binary cursor and "
+ "binary field: %i using default cast", ftype);
+ cast = psyco_default_cast;
+ }
+
+ Dprintf("_pq_fetch_tuples: using cast at %p for type %d", cast, ftype);
+
+ /* success */
+ Py_INCREF(cast);
+ rv = cast;
+
+exit:
+ Py_XDECREF(type);
+ return rv;
+}
+
+static PyObject *
+_make_column(connectionObject *conn, PGresult *pgres, int i)
+{
+ Oid ftype = PQftype(pgres, i);
+ int fsize = PQfsize(pgres, i);
+ int fmod = PQfmod(pgres, i);
+ Oid ftable = PQftable(pgres, i);
+ int ftablecol = PQftablecol(pgres, i);
+
+ columnObject *column = NULL;
+ PyObject *rv = NULL;
+
+ if (!(column = (columnObject *)PyObject_CallObject(
+ (PyObject *)&columnType, NULL))) {
+ goto exit;
+ }
+
+ /* fill the type and name fields */
+ {
+ PyObject *tmp;
+ if (!(tmp = PyInt_FromLong(ftype))) {
+ goto exit;
+ }
+ column->type_code = tmp;
+ }
+
+ {
+ PyObject *tmp;
+ if (!(tmp = conn_text_from_chars(conn, PQfname(pgres, i)))) {
+ goto exit;
+ }
+ column->name = tmp;
+ }
+
+ /* display size is the maximum size of this field result tuples. */
+ Py_INCREF(Py_None);
+ column->display_size = Py_None;
+
+ /* size on the backend */
+ if (fmod > 0) {
+ fmod = fmod - sizeof(int);
+ }
+ if (fsize == -1) {
+ if (ftype == NUMERICOID) {
+ PyObject *tmp;
+ if (!(tmp = PyInt_FromLong((fmod >> 16)))) { goto exit; }
+ column->internal_size = tmp;
+ }
+ else { /* If variable length record, return maximum size */
+ PyObject *tmp;
+ if (!(tmp = PyInt_FromLong(fmod))) { goto exit; }
+ column->internal_size = tmp;
+ }
+ }
+ else {
+ PyObject *tmp;
+ if (!(tmp = PyInt_FromLong(fsize))) { goto exit; }
+ column->internal_size = tmp;
+ }
+
+ /* scale and precision */
+ if (ftype == NUMERICOID) {
+ PyObject *tmp;
+
+ if (!(tmp = PyInt_FromLong((fmod >> 16) & 0xFFFF))) {
+ goto exit;
+ }
+ column->precision = tmp;
+
+ if (!(tmp = PyInt_FromLong(fmod & 0xFFFF))) {
+ goto exit;
+ }
+ column->scale = tmp;
+ }
+
+ /* table_oid, table_column */
+ if (ftable != InvalidOid) {
+ PyObject *tmp;
+ if (!(tmp = PyInt_FromLong((long)ftable))) { goto exit; }
+ column->table_oid = tmp;
+ }
+
+ if (ftablecol > 0) {
+ PyObject *tmp;
+ if (!(tmp = PyInt_FromLong((long)ftablecol))) { goto exit; }
+ column->table_column = tmp;
+ }
+
+ /* success */
+ rv = (PyObject *)column;
+ column = NULL;
+
+exit:
+ Py_XDECREF(column);
+ return rv;
+}
+
RAISES_NEG static int
_pq_fetch_tuples(cursorObject *curs)
{
- int i, *dsize = NULL;
+ int i;
int pgnfields;
- int pgbintuples;
int rv = -1;
PyObject *description = NULL;
PyObject *casts = NULL;
@@ -1244,7 +1379,6 @@ _pq_fetch_tuples(cursorObject *curs)
Py_END_ALLOW_THREADS;
pgnfields = PQnfields(curs->pgres);
- pgbintuples = PQbinaryTuples(curs->pgres);
curs->notuples = 0;
@@ -1255,158 +1389,31 @@ _pq_fetch_tuples(cursorObject *curs)
if (!(casts = PyTuple_New(pgnfields))) { goto exit; }
curs->columns = pgnfields;
- /* calculate the display size for each column (cpu intensive, can be
- switched off at configuration time) */
-#ifdef PSYCOPG_DISPLAY_SIZE
- if (!(dsize = PyMem_New(int, pgnfields))) {
- PyErr_NoMemory();
- goto exit;
- }
- Py_BEGIN_ALLOW_THREADS;
- if (dsize != NULL) {
- int j, len;
- for (i=0; i < pgnfields; i++) {
- dsize[i] = -1;
- }
- for (j = 0; j < curs->rowcount; j++) {
- for (i = 0; i < pgnfields; i++) {
- len = PQgetlength(curs->pgres, j, i);
- if (len > dsize[i]) dsize[i] = len;
- }
- }
- }
- Py_END_ALLOW_THREADS;
-#endif
-
- /* calculate various parameters and typecasters */
+ /* calculate each field's parameters and typecasters */
for (i = 0; i < pgnfields; i++) {
- Oid ftype = PQftype(curs->pgres, i);
- int fsize = PQfsize(curs->pgres, i);
- int fmod = PQfmod(curs->pgres, i);
- Oid ftable = PQftable(curs->pgres, i);
- int ftablecol = PQftablecol(curs->pgres, i);
-
- columnObject *column = NULL;
- PyObject *type = NULL;
+ PyObject *column = NULL;
PyObject *cast = NULL;
- if (!(column = (columnObject *)PyObject_CallObject(
- (PyObject *)&columnType, NULL))) {
+ if (!(column = _make_column(curs->conn, curs->pgres, i))) {
goto exit;
}
+ PyTuple_SET_ITEM(description, i, (PyObject *)column);
- /* fill the right cast function by accessing three different dictionaries:
- - the per-cursor dictionary, if available (can be NULL or None)
- - the per-connection dictionary (always exists but can be null)
- - the global dictionary (at module level)
- if we get no defined cast use the default one */
-
- if (!(type = PyInt_FromLong(ftype))) {
- goto err_for;
- }
- Dprintf("_pq_fetch_tuples: looking for cast %d:", ftype);
- cast = curs_get_cast(curs, type);
-
- /* else if we got binary tuples and if we got a field that
- is binary use the default cast
- FIXME: what the hell am I trying to do here? This just can't work..
- */
- if (pgbintuples && cast == psyco_default_binary_cast) {
- Dprintf("_pq_fetch_tuples: Binary cursor and "
- "binary field: %i using default cast",
- PQftype(curs->pgres,i));
- cast = psyco_default_cast;
+ if (!(cast = _get_cast(curs, curs->pgres, i))) {
+ goto exit;
}
-
- Dprintf("_pq_fetch_tuples: using cast at %p for type %d",
- cast, PQftype(curs->pgres,i));
- Py_INCREF(cast);
PyTuple_SET_ITEM(casts, i, cast);
+ }
- /* 1/ fill the other fields */
- {
- PyObject *tmp;
- if (!(tmp = conn_text_from_chars(
- curs->conn, PQfname(curs->pgres, i)))) {
- goto err_for;
- }
- column->name = tmp;
- }
- column->type_code = type;
- type = NULL;
-
- /* 2/ display size is the maximum size of this field result tuples. */
- if (dsize && dsize[i] >= 0) {
- PyObject *tmp;
- if (!(tmp = PyInt_FromLong(dsize[i]))) { goto err_for; }
- column->display_size = tmp;
- }
-
- /* 3/ size on the backend */
- if (fmod > 0) fmod = fmod - sizeof(int);
- if (fsize == -1) {
- if (ftype == NUMERICOID) {
- PyObject *tmp;
- if (!(tmp = PyInt_FromLong((fmod >> 16)))) { goto err_for; }
- column->internal_size = tmp;
- }
- else { /* If variable length record, return maximum size */
- PyObject *tmp;
- if (!(tmp = PyInt_FromLong(fmod))) { goto err_for; }
- column->internal_size = tmp;
- }
- }
- else {
- PyObject *tmp;
- if (!(tmp = PyInt_FromLong(fsize))) { goto err_for; }
- column->internal_size = tmp;
- }
-
- /* 4,5/ scale and precision */
- if (ftype == NUMERICOID) {
- PyObject *tmp;
-
- if (!(tmp = PyInt_FromLong((fmod >> 16) & 0xFFFF))) {
- goto err_for;
- }
- column->precision = tmp;
-
- if (!(tmp = PyInt_FromLong(fmod & 0xFFFF))) {
- goto err_for;
- }
- column->scale = tmp;
- }
-
- /* table_oid, table_column */
- if (ftable != InvalidOid) {
- PyObject *tmp;
- if (!(tmp = PyInt_FromLong((long)ftable))) { goto err_for; }
- column->table_oid = tmp;
- }
-
- if (ftablecol > 0) {
- PyObject *tmp;
- if (!(tmp = PyInt_FromLong((long)ftablecol))) { goto err_for; }
- column->table_column = tmp;
- }
-
- PyTuple_SET_ITEM(description, i, (PyObject *)column);
- column = NULL;
-
- continue;
+ curs->description = description;
+ description = NULL;
-err_for:
- Py_XDECREF(type);
- Py_XDECREF(column);
- goto exit;
- }
+ curs->casts = casts;
+ casts = NULL;
- curs->description = description; description = NULL;
- curs->casts = casts; casts = NULL;
rv = 0;
exit:
- PyMem_Free(dsize);
Py_XDECREF(description);
Py_XDECREF(casts);
@@ -1417,6 +1424,7 @@ exit:
return rv;
}
+
void
_read_rowcount(cursorObject *curs)
{
diff --git a/setup.cfg b/setup.cfg
index a5efdcf..f1f57e6 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,9 +1,6 @@
[build_ext]
-define=
-
-# PSYCOPG_DISPLAY_SIZE enable display size calculation (a little slower)
-# HAVE_PQFREEMEM should be defined on PostgreSQL >= 7.4
# PSYCOPG_DEBUG can be added to enable verbose debug information
+define=
# "pg_config" is required to locate PostgreSQL headers and libraries needed to
# build psycopg2. If pg_config is not in the path or is installed under a