Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

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

Ouverte
#1,390 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@HardMax71 y travaille déjà.

Depuis le 13/10/2026.

  • #1391 par @HardMax71 — ouverte

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
18/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
À l'abandon
Stack technique
postgresql, python
Domaine
databases

Piste de recherche

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.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

  • 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.

Langage dominant
Python
Étoiles
8.1k
Forks
477
Merge moyen
1 j 7 h
PR mergées (30 j)
23

Préparer son environnement

Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de MagicStack/asyncpg

Toutes les issues de MagicStack/asyncpg

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.