Queries with more than 32767 arguments are refused, PostgreSQL accepts 65535
Maintainer antworten meist innerhalb von 1 Tag
Bewertung
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Anfängerfreundlichkeit
- 18/100
Rechercherichtung
The limit lives in asyncpg/protocol/prepared_stmt.pyx (the check near lines 130-132 and the count handling near 348-353) and its declaration in prepared_stmt.pxd. Run the test named test_prepare_28_max_args to see the current 32767 ceiling. Pull request #1391 already carries this change, so review or build on that rather than starting a parallel fix. Done means the counts are unsigned, the limit is 65535, and the test passes.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
- asyncpg version: 0.32.0, same on master (13b0191)
- PostgreSQL version: 17
- Do you use a PostgreSQL SaaS? If so, which? Can you reproduce
the issue with a local PostgreSQL install?: no, local Dockerpostgres:17 - Python version: 3.12
- Platform: macOS
- Do you use pgbouncer?: no
- Did you install asyncpg with pip?: yes, and built master locally for the check below
- If you built asyncpg locally, which version of Cython did you use?: 3.2.x
- Can the issue be reproduced under both asyncio and
uvloop?: tried asyncio only; the limit is in the protocol code
asyncpg refuses more than 32767 query arguments (prepared_stmt.pyx#L130-L132) and keeps the parameter count in int16_t (prepared_stmt.pxd#L24, prepared_stmt.pyx#L348-L353). The limit comes from #127, where the Int16 in the Bind message was read as signed.
PostgreSQL reads that count as unsigned: exec_bind_message takes it with pq_getmsgint(input_message, 2) (postgres.c#L1725), which returns a uint16 (pqformat.c#L419-L430), and the docs list 65,535 query parameters as the limit (PostgreSQL Limits, listed since 12). libpq allows the same (libpq-fe.h#L490), so psycopg runs the same statements with up to 65535 parameters.
As a result, a multi-row INSERT ... VALUES has to be split at half of what the server accepts.
import asyncio
import importlib.metadata as md
import asyncpg
import psycopg
DSN = "postgresql://postgres@localhost/postgres"
def query(n, mark):
return "SELECT count(*) FROM (VALUES {}) v(x)".format(
", ".join("({}::int)".format(mark(i)) for i in range(1, n + 1))
)
async def main():
print("asyncpg", md.version("asyncpg"), "psycopg", md.version("psycopg"))
conn = await asyncpg.connect(DSN)
for n in (32767, 32768, 65535):
try:
print(f"asyncpg {n}:", await conn.fetchval(query(n, lambda i: f"${i}"), *range(n)))
except asyncpg.InterfaceError as e:
print(f"asyncpg {n}: {e}")
with psycopg.connect(DSN) as pg:
print(f"psycopg {n}:", pg.execute(query(n, lambda i: "%s"), range(n), prepare=True).fetchone()[0])
await conn.close()
asyncio.run(main())
asyncpg 0.33.0.dev0+13b0191 psycopg 3.3.6
asyncpg 32767: 32767
psycopg 32767: 32767
asyncpg 32768: the number of query arguments cannot exceed 32767
psycopg 32768: 32768
asyncpg 65535: the number of query arguments cannot exceed 32767
psycopg 65535: 65535
Keeping the counts as uint16_t and raising the check to 65535 fixes it, and the bytes on the wire stay the same for up to 32767 arguments.
I have that ready with an updated test_prepare_28_max_args and will open a PR.
- Vorherrschende Sprache
- Python
- Sterne
- 8.1k
- Forks
- 477
- Ø Merge
- 1 T. 7 Std.
- Gemergte PRs (30 T.)
- 23
Entwicklungsumgebung
Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus MagicStack/asyncpg
-
Failed BEGIN leaves Connection._top_xact set; every later transaction becomes a SAVEPOINT and fails with NoActiveSQLTransactionErrorEvtl. vergeben @devtechedge hat das vor 9 Tagen übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 35/100
MagicStack/asyncpg#1386 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Connect call failed error doesn't distinguish port mismatch from "server not running"Evtl. vergeben @aryansk hat das vor 62 Tagen übernommen. Offen
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 72/100
MagicStack/asyncpg#1342 ·
Maintainer antworten meist innerhalb von 1 Tag
-
TypeError in asyncpg.connect() for specific parameters when values are not str enoughEvtl. vergeben @pranjalm37 hat das vor 65 Tagen übernommen. Offen
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 56/100
MagicStack/asyncpg#1340 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
setup.py relies on deprecated pkg_resourcesEvtl. vergeben @jasonwbarnett hat das vor 93 Tagen übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 28/100
MagicStack/asyncpg#1337 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 42/100
MagicStack/asyncpg#1330 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in MagicStack/asyncpg
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
omegaup/omegaup#10353 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 5 Tagen
-
bot-triaged module: LrScheduler module: optimizer triaged
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
Maintainer antworten meist innerhalb von 1 Tag
-
documentation glm5 llm-model
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
vllm-project/vllm-ascend#19062 ·
Maintainer antworten meist innerhalb von 1 Tag
-
author-page correction
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
acl-org/acl-anthology#10496 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag