Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

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

Abierto
#1,390 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@HardMax71 ya está trabajando en esto.

Desde el 13/10/2026.

  • #1391 de @HardMax71 — abierto

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
18/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Estancado
Stack tecnológico
postgresql, python
Área
databases

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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

Lenguaje dominante
Python
Estrellas
8.1k
Forks
477
Merge medio
1 d 7 h
PR fusionados (30 d)
23

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de MagicStack/asyncpg

Todos los issues de MagicStack/asyncpg

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.