Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
lelit opened this issue May 9, 2017 · 2 comments
Closed
Assignees
Labels

Comments

@lelit
Copy link
Contributor

lelit commented May 9, 2017

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',
    ....
)
@elprans
Copy link
Member

elprans commented May 9, 2017

Confirmed.

@elprans elprans self-assigned this May 9, 2017
@elprans elprans added the bug label May 9, 2017
elprans added a commit that referenced this issue May 9, 2017
set_builtin_type_codec() flushes the codec cache, so internal codec
aliasing (for enums and fallback) must use a version that doesn't
kill the cache.

Fixes: #133.
elprans added a commit that referenced this issue May 9, 2017
set_builtin_type_codec() flushes the codec cache, so internal codec
aliasing (for enums and fallback) must use a version that doesn't
kill the cache.

Fixes: #133, #122.
@lelit
Copy link
Contributor Author

lelit commented May 9, 2017

Thank you!

@1st1 1st1 closed this as completed in #134 May 9, 2017
1st1 pushed a commit that referenced this issue May 9, 2017
set_builtin_type_codec() flushes the codec cache, so internal codec
aliasing (for enums and fallback) must use a version that doesn't
kill the cache.

Fixes: #133, #122.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants