Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

Queries with more than 32767 arguments are refused, PostgreSQL accepts 65535

Offen
#1,390 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

@HardMax71 arbeitet bereits daran.

Seit 13.10.2026.

  • #1391 von @HardMax71 — offen

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
18/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Veraltet
Tech-Stack
postgresql, python
Bereich
databases

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 Docker postgres: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

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus MagicStack/asyncpg

Alle Issues in MagicStack/asyncpg

Ähnliche Issues

Weitere Issues zu Python

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.