Skip to content

"RuntimeError: no decoder for OID 3912", depending on execution order #133

Closed
@lelit

Description

@lelit

I'm using asyncpg 0.10.1, Python 3.6.1 and PostgreSQL 9.6.2.

I started to hit a strange problem this morning, with a query involving a DateRange column. I was really surprised, because the query is almost equivalent to several others, and it took several hours to distill the even more surprising script:

import sys

import asyncio
import asyncpg


SQL1 = """\
SELECT r.size AS "Size",
       r.validity
FROM shelf.attachments AS a
JOIN shelf.resources AS r ON r.id = a.resource_id
WHERE a.object_kind = $1::notable_t
  AND a.object_id = $2::UUID
"""


SQL2 = """\
SELECT a.id,
       a.resource_id
FROM shelf.attachments AS a
WHERE a.object_kind = $1::notable_t
  AND a.object_id = $2::UUID
"""


async def run(order):
    conn = await asyncpg.connect(user='user', password='password',
                                 database='database', host='127.0.0.1', port=5423)
    if order == 'good':
        stmts = [SQL2, SQL1]
    else:
        stmts = [SQL1, SQL2]

    for stmt in stmts:
        values = await conn.fetch(stmt, 'risk.Company', '3332bc6c-3319-11e7-a713-0242ac120002')
        print(values)

    await conn.close()


def main():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run('good' if len(sys.argv) == 1 else 'bad'))


if __name__ == '__main__':
    main()

Executing the script without arguments, I get:

$ python test1.py
[<Record id=UUID('333b8f86-3319-11e7-a713-0242ac120002') resource_id=UUID('33385b9a-3319-11e7-a713-0242ac120002')>]
[<Record Size=59329 validity=<Range [datetime.date(2017, 5, 7), datetime.date(9999, 12, 31))>>]

With an arbitrary argument the script executes the statements in a different order, and I get:

$ python test1.py foo
Traceback (most recent call last):
  File "test1.py", line 47, in <module>
    main()
  File "test1.py", line 43, in main
    loop.run_until_complete(run('good' if len(sys.argv) == 1 else 'bad'))
  File ".../python3.6/asyncio/base_events.py", line 466, in run_until_complete
    return future.result()
  File "test1.py", line 35, in run
    values = await conn.fetch(stmt, 'risk.Company', '3332bc6c-3319-11e7-a713-0242ac120002')
  File "/tmp/apg/lib/python3.6/site-packages/asyncpg/connection.py", line 340, in fetch
    return await self._execute(query, args, 0, timeout)
  File "/tmp/apg/lib/python3.6/site-packages/asyncpg/connection.py", line 651, in _execute
    return await self._do_execute(query, executor, timeout)
  File "/tmp/apg/lib/python3.6/site-packages/asyncpg/connection.py", line 672, in _do_execute
    result = await executor(stmt, None)
  File "asyncpg/protocol/protocol.pyx", line 162, in bind_execute (asyncpg/protocol/protocol.c:57595)
  File "asyncpg/protocol/prepared_stmt.pyx", line 95, in asyncpg.protocol.protocol.PreparedStatementState._encode_bind_msg (asyncpg/protocol/protocol.c:53417)
  File "asyncpg/protocol/prepared_stmt.pyx", line 162, in asyncpg.protocol.protocol.PreparedStatementState._ensure_rows_decoder (asyncpg/protocol/protocol.c:54254)
RuntimeError: no decoder for OID 3912

In other words, it seems that the source of the problem is not the statement itself, but rather when it gets executed.

If needed, I'm willing to try to reproduce the issue with plain data types: above, the notable_t is an enum defined as

CREATE TYPE notable_t AS ENUM (
    'risk.Company',
    'risk.CompanySite',
    ....
)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions