Skip to content

Commit d27dda7

Browse files
committed
Do not split out seconds when decoding interval in tuple mode.
This makes interval consistent with other datetime types.
1 parent a5413eb commit d27dda7

File tree

3 files changed

+14
-19
lines changed

3 files changed

+14
-19
lines changed

asyncpg/connection.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -798,8 +798,7 @@ async def set_type_codec(self, typename, *,
798798
+-----------------+---------------------------------------------+
799799
| Type | Tuple layout |
800800
+=================+=============================================+
801-
| ``interval`` | (``months``, ``days``, ``seconds``, |
802-
| | ``microseconds``) |
801+
| ``interval`` | (``months``, ``days``, ``microseconds``) |
803802
+-----------------+---------------------------------------------+
804803
| ``date`` | (``date ordinal relative to Jan 1 2000``,) |
805804
| | ``-2^31`` for negative infinity timestamp |
@@ -845,14 +844,13 @@ async def set_type_codec(self, typename, *,
845844
... ndelta = delta.normalized()
846845
... return (ndelta.years * 12 + ndelta.months,
847846
... ndelta.days,
848-
... (ndelta.hours * 3600 +
847+
... ((ndelta.hours * 3600 +
849848
... ndelta.minutes * 60 +
850-
... ndelta.seconds),
851-
... ndelta.microseconds)
849+
... ndelta.seconds) * 1000000 +
850+
... ndelta.microseconds))
852851
... def decoder(tup):
853852
... return relativedelta(months=tup[0], days=tup[1],
854-
... seconds=tup[2],
855-
... microseconds=tup[3])
853+
... microseconds=tup[2])
856854
... await con.set_type_codec(
857855
... 'interval', schema='pg_catalog', encoder=encoder,
858856
... decoder=decoder, format='tuple')

asyncpg/protocol/codecs/datetime.pyx

+8-11
Original file line numberDiff line numberDiff line change
@@ -339,21 +339,19 @@ cdef interval_encode_tuple(ConnectionSettings settings, WriteBuffer buf,
339339
cdef:
340340
int32_t months
341341
int32_t days
342-
int64_t seconds
343-
int32_t microseconds
342+
int64_t microseconds
344343

345-
if len(obj) != 4:
344+
if len(obj) != 3:
346345
raise ValueError(
347-
'interval tuple encoder: expecting 4 elements '
346+
'interval tuple encoder: expecting 3 elements '
348347
'in tuple, got {}'.format(len(obj)))
349348

350349
months = obj[0]
351350
days = obj[1]
352-
seconds = obj[2]
353-
microseconds = obj[3]
351+
microseconds = obj[2]
354352

355353
buf.write_int32(16)
356-
_encode_time(buf, seconds, microseconds)
354+
buf.write_int64(microseconds)
357355
buf.write_int32(days)
358356
buf.write_int32(months)
359357

@@ -385,14 +383,13 @@ cdef interval_decode_tuple(ConnectionSettings settings, FastReadBuffer buf):
385383
cdef:
386384
int32_t days
387385
int32_t months
388-
int64_t seconds = 0
389-
uint32_t microseconds = 0
386+
int64_t microseconds
390387

391-
_decode_time(buf, &seconds, &microseconds)
388+
microseconds = hton.unpack_int64(buf.read(8))
392389
days = hton.unpack_int32(buf.read(4))
393390
months = hton.unpack_int32(buf.read(4))
394391

395-
return (months, days, seconds, microseconds)
392+
return (months, days, microseconds)
396393

397394

398395
cdef init_datetime_codecs():

tests/test_codecs.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ async def test_custom_codec_override_tuple(self):
10511051
"tab.v AT TIME ZONE 'EST'"),
10521052
('timestamptz', (2**63 - 1,), 'infinity'),
10531053
('timestamptz', (-2**63,), '-infinity'),
1054-
('interval', (2, 3, 0, 0), '2 mons 3 days')
1054+
('interval', (2, 3, 1), '2 mons 3 days 00:00:00.000001')
10551055
]
10561056

10571057
conn = await self.cluster.connect(database='postgres', loop=self.loop)

0 commit comments

Comments
 (0)