test: allow to trace libpq to STDERR, rename option to --pq-trace
By using STDERR, we get the trace directly in pytest output for failing
tests. Though this requires care when used in combination with
--capture=sys because this would make sys.stderr an in-memory file.
When STDERR is used, we don't insert the header since the test case
identifier will be interleaved already.
fix: also sync nested pipeline when a transaction is active
Upon enter, transaction() checks the in-transaction status to determine
if a BEGIN (when IDLE) or a SAVEPOINT (otherwise) should be inserted.
However, in pipeline mode, if the pipeline is in "implicit transaction"
(i.e. it has no active BEGIN) and statements have been sent, the
in-transaction status might be ACTIVE if those statements have not yet
completed (typically, when results have not been fetched).
By issuing a sync() before entering a nested pipeline (which will happen
when entering transaction(), if already within a pipeline), we force
completion of those statements, and thus get a predictable
in-transaction status before entering the transaction() block.
fix: catch any type of error if ZoneInfo creation fails
OSError would be enough to solve the problem reported in #371. However,
in case of error, Windows C implementation segfaults. I would prefer to
not chase this error just because of weirdness in the tzdata external
library, so let's cast a wider net.
fix: make sure to pass a port number to getaddrinfo
Was passing an empty string by mistake, if no port was specified. Mostly
not a problem, except on some platforms, where it causes an
"unrecognized service" error.
Daniele Varrazzo [Tue, 23 Aug 2022 22:39:40 +0000 (00:39 +0200)]
fix: avoid all uses of PQconn.send_query in pipeline mode
We stopped using it in normal querying because, until libpq 14.4, the
libpq complained about "message type 0x33 arrived from server while
idle" (see #314). But usage remained for internal queries such as BEGIN.
In libpq 14.5, Postgres devs tried to fix the issue... and broke
PQsendQuery altogether :(
Hopefully the issue will be solved in future libpq versions, but we can
work around it completely.
Daniele Varrazzo [Mon, 15 Aug 2022 00:46:19 +0000 (02:46 +0200)]
fix(psycopg_c): guard PQflush calls for invalid connections
Unlike other libpq functions, PQflush() doesn't have a guard for invalid
connections and will segfault if the connection gets closed.
Also check the return value of the PQflush calls: as we are not using
the wrapped version pgconn.flush(), the function doesn't automatically
throw an exception on failure.
Daniele Varrazzo [Fri, 12 Aug 2022 23:35:41 +0000 (01:35 +0200)]
ci: specify non-editable install in tox tests
Work around tox-dev/tox#2479 (editable installs in tox broken by setuptools
v64) and tox-dev/tox#2480 (failure to use `toxinidir` in `deps`).
Use -e consistently in the linting steps instead, because they are
defined with skip_install=True so it seems a good idea to use it. These
steps don't seem affect by the setuptools issue.
This allows to write binary format even when the query has executed no
COPY operation.
Notice that now we have introduced tests that convert sample_records
into sample_binary: because small numbers would be dumped to int2, use
values large enough to require int4.
perf(copy): use non-thread/task copy writers by default
Further benchmarks show no performance improvement using a writer
thread, and a slight slowdown using a writer async task. If that's the
case we can keep it simpler.
Daniele Varrazzo [Sat, 11 Jun 2022 22:47:50 +0000 (00:47 +0200)]
refactor(copy): make the writer entirely responsible of the libpq copy state
This way we can create a writer which is entirely independent from the
libpq and the connection, which is useful, for instance, to format a
file with copy data.
Daniele Varrazzo [Sat, 11 Jun 2022 14:21:38 +0000 (16:21 +0200)]
refactor(copy): add Writer object
This separation of responsibility will allow to:
- create writers that e.g. produce a file rather than writing to a
connection;
- create writers that write directly instead of using a queue (see
https://github.com/psycopg/psycopg/discussions/111 for an example of users
unhappy about that. I still don't see their nervousness justified, but
I'm ok to provide them an escape hatch if it's easy to implement).