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

Can't resolve tuple argument types #476

Closed
LEW21 opened this issue Sep 17, 2019 · 3 comments
Closed

Can't resolve tuple argument types #476

LEW21 opened this issue Sep 17, 2019 · 3 comments
Labels

Comments

@LEW21
Copy link

LEW21 commented Sep 17, 2019

  • asyncpg version: 0.18.3
  • PostgreSQL version: 11.5
  • Do you use a PostgreSQL SaaS? If so, which? Can you reproduce
    the issue with a local PostgreSQL install?
    : No, it's on docker
  • Python version: 3.7.4
  • Platform: Linux
  • Do you use pgbouncer?: No
  • Did you install asyncpg with pip?: Yes
  • If you built asyncpg locally, which version of Cython did you use?: No
  • Can the issue be reproduced under both asyncio and
    uvloop?
    : Didn't try uvloop.

asyncpg is unable to resolve argument types for the following SQL query:

SELECT * FROM lorem WHERE (first_id, second_id) = $1

Complete example - this script fails:

import asyncio
import asyncpg
import os

async def main():
    conn = await asyncpg.connect(os.environ['DATABASE_URL'])
    try:
        await conn.execute(
            """
            create table "lorem" (
                "first_id" int,
                "second_id" int,
                primary key ("first_id", "second_id")
            );
            """
        )
        await conn.execute("insert into lorem values (5, 5)")
    except asyncpg.DuplicateTableError:
        pass

    sql = "SELECT * FROM lorem WHERE (first_id) = $1"
    print(sql)
    print(await conn.fetch(sql, 5)) # Works

    sql = "SELECT * FROM lorem WHERE (first_id, second_id) = $1"
    print(sql)
    print(await conn.fetch(sql, (5, 5))) # Crashes

asyncio.run(main())

with

SELECT * FROM lorem WHERE (first_id) = $1
[<Record first_id=5 second_id=5>]
SELECT * FROM lorem WHERE (first_id, second_id) = $1
Traceback (most recent call last):
  File "nano.py", line 31, in <module>
    asyncio.run(main())
  File "/usr/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.7/asyncio/base_events.py", line 579, in run_until_complete
    return future.result()
  File "nano.py", line 29, in main
    print(await conn.fetch(sql, (5, 5))) # Crashes
  File "/home/lew21/.venv/lib/python3.7/site-packages/asyncpg/connection.py", line 421, in fetch
    return await self._execute(query, args, 0, timeout)
  File "/home/lew21/.venv/lib/python3.7/site-packages/asyncpg/connection.py", line 1414, in _execute
    query, args, limit, timeout, return_status=return_status)
  File "/home/lew21/.venv/lib/python3.7/site-packages/asyncpg/connection.py", line 1422, in __execute
    return await self._do_execute(query, executor, timeout)
  File "/home/lew21/.venv/lib/python3.7/site-packages/asyncpg/connection.py", line 1434, in _do_execute
    stmt = await self._get_statement(query, None)
  File "/home/lew21/.venv/lib/python3.7/site-packages/asyncpg/connection.py", line 356, in _get_statement
    'in {} attempts'.format(tries)
asyncpg.exceptions._base.InternalClientError: could not resolve query result and/or argument types in 6 attempts
@eirnym
Copy link

eirnym commented Sep 17, 2019

I haven't seen there any support of tuple unpacking. I'd separate parameters to $1 and $2 to avoid such problem

@LEW21
Copy link
Author

LEW21 commented Sep 17, 2019

I haven't seen there any support of tuple unpacking. I'd separate parameters to $1 and $2 to avoid such problem

Unfortunately, I can't do it - I'm using WHERE (first_id, second_id) = any($1) and providing a list of tuples.

@elprans
Copy link
Member

elprans commented Sep 17, 2019

This is a PostgreSQL protocol limitation. Anonymous row types (tuples) cannot be described. The error handling in this case could be better, sure.

@LEW21 If you can afford it, I would suggest declaring an explicit composite type:

CREATE TYPE id_pair AS (first_id int, second_id int)

and then

WHERE (first_id, second_id) = any($1::id_pair[])

@1st1 1st1 added the question label Nov 19, 2019
elprans added a commit that referenced this issue Nov 27, 2020
Currently asyncpg would crash with an arcane "could not resolve query
result and/or argument types in 6 attempts", which isn't helpful.  Do
the right thing by raising an `UnsupportedClientFeatureError`
explicitly instead.

Fixes #476.
elprans added a commit that referenced this issue Nov 29, 2020
Currently asyncpg would crash with an arcane "could not resolve query
result and/or argument types in 6 attempts", which isn't helpful.  Do
the right thing by raising an `UnsupportedClientFeatureError`
explicitly instead.

Fixes #476.
@elprans elprans closed this as completed in 7252dbe Dec 2, 2020
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

4 participants