Daniele Varrazzo [Fri, 12 Feb 2021 01:23:16 +0000 (02:23 +0100)]
Don't recalculate loaders when not needed
The case it's not needed is when the new result is guaranteed to have
the same fields as the previous one. This happens querying in single-row
mode and on server-side cursors fetch.
Daniele Varrazzo [Fri, 22 Jan 2021 21:30:08 +0000 (22:30 +0100)]
Dump time and timestamp naive and tz-aware with the respective oids
Using the tz version of the data types is ok enough for most uses,
because Postgres can downgrade the type to naive, but ranges don't have
an implicit cast and the exact type of the range subtype is necessary.
Daniele Varrazzo [Thu, 21 Jan 2021 03:05:33 +0000 (04:05 +0100)]
Have a single Range class, not one per subtype
There are two problems here, so this doesn't work. One, which will be
solved, is to have a registry of types attached to an adaptation
context: a TODO in already several places, so this will be solved.
Before that we don't really have a way to find back e.g. the oid of a
custom range on strings starting from Range('a', 'b').
The second problem, more serious, is that Postgres doesn't cast
int4range <-> int8range and tsrange <-> tstzrange. The latter pair can
be solved with a two steps dumper choosing between tz aware and not. The
first I don't have in mind how to solve it: Given Range(1,2) I wouldn't
know if int4 or int8 should be used, and Postgres doesn't seem very
forgiving. Probably we should go unknown.
Daniele Varrazzo [Wed, 20 Jan 2021 12:23:06 +0000 (13:23 +0100)]
Don't require a Transformer roundtrip to choose the specific int dumper
They are static object, they require no customisation with the
connection. I don't expect anyone wanting to subclass them; if they
do they will deal with the whole 5 objects.
Daniele Varrazzo [Wed, 20 Jan 2021 01:46:45 +0000 (02:46 +0100)]
Adapt the dumper used to the value of the objects
Added a second dispatch to allow a dumper to upgrade to a specialised
version. Currently used to dump int to the smallest Postgres type
holding that value and to dump lists of object into typed arrays.
This change allows to write queries more naturally as no ``::int`` cast
should be needed anymore e.g. in date + int or jsonb ->> int.
Only Python implementation; C version to be implemented yet.
Daniele Varrazzo [Sat, 16 Jan 2021 02:06:56 +0000 (03:06 +0100)]
Declare all loaders to receive an object supporting the buffer interface
There isn't in mypy such an object, so just use `Union[bytes, bytearray,
memoryview]`
Avoid a memory copy passing data from the Transformer to the loaders.
I had started exercising this code path by adding copy tests, but after
dropping the extra copy the same path is now exercised by any select, so
I've stopped doing that.
Daniele Varrazzo [Wed, 13 Jan 2021 14:46:49 +0000 (15:46 +0100)]
Choose automatically text or binary format using %s placeholders
A format can be enforced using %b or %t placeholders.
Use binary formats dumpers if available, otherwise use text dumpers.
Python str are an exception: prefer text dumper, because it will dump
with format 0, so Postgres can cast the value to any format.
Special-case empty lists to be always dumped as textual unknown '{}' so
that Postgres can cast them into whatever array it fancies.
Daniele Varrazzo [Wed, 13 Jan 2021 13:38:00 +0000 (14:38 +0100)]
Dropped explicit support for Postgres 9.6
People can still use it, but they should likely disable stored procedure
on a connection and avoid to use executemany, on top of adding plenty of
cast.
Daniele Varrazzo [Wed, 13 Jan 2021 00:02:13 +0000 (01:02 +0100)]
Don't return None as text in Python 9.6
This makes to require a cast on pretty much any placeholder that might
receive a None, which is really asking too much.
Exploratory commit to test what can be done with PG 9.6. The result
shows that in PG 9.6 it's pretty much impossible to use prepared
statements: neither for executemany nor for preparation. Tests failing:
Daniele Varrazzo [Tue, 12 Jan 2021 21:44:28 +0000 (22:44 +0100)]
Added dumpers row
Speed up repeated dumps on the same query (e.g. in executemany, in copy,
for composite types).
Things are a bit iffy around empty list dumping. As a tradeoff, prefer
that empty list don't behave too differently from non-empty list, but
accept that text and binary work differently (because it doesn't seem
possible to pass an array as unknown in binary, whereas in text '{}'
works ok).