diff options
author | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2018-10-15 00:58:32 +0100 |
---|---|---|
committer | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2018-10-15 00:58:32 +0100 |
commit | b205764fdde4549c48c27841aa17e6c7f499e808 (patch) | |
tree | 1475eb57dc854ea4a1dc93c1c6a567e6fc584e5c /psycopg/pqpath.c | |
parent | e7227ce87b8da75fef1a3376ebb47e2bf20f6063 (diff) | |
parent | 7a5edff6c66a0410d6fecd4445980aabafc3ab4a (diff) | |
download | psycopg2-errors-module.tar.gz |
Merge branch 'master' into errors-moduleerrors-module
Diffstat (limited to 'psycopg/pqpath.c')
-rw-r--r-- | psycopg/pqpath.c | 76 |
1 files changed, 39 insertions, 37 deletions
diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c index 75ab268..04a34a2 100644 --- a/psycopg/pqpath.c +++ b/psycopg/pqpath.c @@ -41,6 +41,7 @@ #include "psycopg/typecast.h" #include "psycopg/pgtypes.h" #include "psycopg/error.h" +#include "psycopg/column.h" #include "psycopg/libpq_support.h" #include "libpq-fe.h" @@ -108,7 +109,7 @@ exit: /* Returns the Python exception corresponding to an SQLSTATE error code. A list of error codes can be found at: - http://www.postgresql.org/docs/current/static/errcodes-appendix.html */ + https://www.postgresql.org/docs/current/static/errcodes-appendix.html */ BORROWED static PyObject * exception_from_sqlstate(const char *sqlstate) { @@ -1150,12 +1151,13 @@ pq_send_query(connectionObject *conn, const char *query) * The function will block only if a command is active and the * necessary response data has not yet been read by PQconsumeInput. * - * The result should be disposed using PQclear() + * The result should be disposed of using PQclear() */ PGresult * pq_get_last_result(connectionObject *conn) { PGresult *result = NULL, *res; + ExecStatusType status; /* Read until PQgetResult gives a NULL */ while (NULL != (res = PQgetResult(conn->pgconn))) { @@ -1168,11 +1170,15 @@ pq_get_last_result(connectionObject *conn) PQclear(result); } result = res; + status = PQresultStatus(result); + Dprintf("pq_get_last_result: got result %s", PQresStatus(status)); - /* After entering copy both mode, libpq will make a phony + /* After entering copy mode, libpq will make a phony * PGresult for us every time we query for it, so we need to * break out of this endless loop. */ - if (PQresultStatus(result) == PGRES_COPY_BOTH) { + if (status == PGRES_COPY_BOTH + || status == PGRES_COPY_OUT + || status == PGRES_COPY_IN) { break; } } @@ -1245,12 +1251,17 @@ _pq_fetch_tuples(cursorObject *curs) 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); - PyObject *dtitem = NULL; + columnObject *column = NULL; PyObject *type = NULL; PyObject *cast = NULL; - if (!(dtitem = PyTuple_New(7))) { goto exit; } + if (!(column = (columnObject *)PyObject_CallObject( + (PyObject *)&columnType, NULL))) { + goto exit; + } /* fill the right cast function by accessing three different dictionaries: - the per-cursor dictionary, if available (can be NULL or None) @@ -1287,20 +1298,16 @@ _pq_fetch_tuples(cursorObject *curs) curs->conn, PQfname(curs->pgres, i)))) { goto err_for; } - PyTuple_SET_ITEM(dtitem, 0, tmp); + column->name = tmp; } - PyTuple_SET_ITEM(dtitem, 1, type); + 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; } - PyTuple_SET_ITEM(dtitem, 2, tmp); - } - else { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(dtitem, 2, Py_None); + column->display_size = tmp; } /* 3/ size on the backend */ @@ -1309,18 +1316,18 @@ _pq_fetch_tuples(cursorObject *curs) if (ftype == NUMERICOID) { PyObject *tmp; if (!(tmp = PyInt_FromLong((fmod >> 16)))) { goto err_for; } - PyTuple_SET_ITEM(dtitem, 3, tmp); + column->internal_size = tmp; } else { /* If variable length record, return maximum size */ PyObject *tmp; if (!(tmp = PyInt_FromLong(fmod))) { goto err_for; } - PyTuple_SET_ITEM(dtitem, 3, tmp); + column->internal_size = tmp; } } else { PyObject *tmp; if (!(tmp = PyInt_FromLong(fsize))) { goto err_for; } - PyTuple_SET_ITEM(dtitem, 3, tmp); + column->internal_size = tmp; } /* 4,5/ scale and precision */ @@ -1330,40 +1337,35 @@ _pq_fetch_tuples(cursorObject *curs) if (!(tmp = PyInt_FromLong((fmod >> 16) & 0xFFFF))) { goto err_for; } - PyTuple_SET_ITEM(dtitem, 4, tmp); + column->precision = tmp; if (!(tmp = PyInt_FromLong(fmod & 0xFFFF))) { - PyTuple_SET_ITEM(dtitem, 5, tmp); + goto err_for; } - PyTuple_SET_ITEM(dtitem, 5, tmp); - } - else { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(dtitem, 4, Py_None); - Py_INCREF(Py_None); - PyTuple_SET_ITEM(dtitem, 5, Py_None); + column->scale = tmp; } - /* 6/ FIXME: null_ok??? */ - Py_INCREF(Py_None); - PyTuple_SET_ITEM(dtitem, 6, Py_None); + /* table_oid, table_column */ + if (ftable != InvalidOid) { + PyObject *tmp; + if (!(tmp = PyInt_FromLong((long)ftable))) { goto err_for; } + column->table_oid = tmp; + } - /* Convert into a namedtuple if available */ - if (Py_None != psyco_DescriptionType) { - PyObject *tmp = dtitem; - dtitem = PyObject_CallObject(psyco_DescriptionType, tmp); - Py_DECREF(tmp); - if (NULL == dtitem) { goto err_for; } + if (ftablecol > 0) { + PyObject *tmp; + if (!(tmp = PyInt_FromLong((long)ftablecol))) { goto err_for; } + column->table_column = tmp; } - PyTuple_SET_ITEM(description, i, dtitem); - dtitem = NULL; + PyTuple_SET_ITEM(description, i, (PyObject *)column); + column = NULL; continue; err_for: Py_XDECREF(type); - Py_XDECREF(dtitem); + Py_XDECREF(column); goto exit; } |