Skip to content

PgSQL: spec-valid Bind with num_param_formats=1 and 0 parameters rejected ("Invalid param format count") #5899

Description

@renecannao

Summary

ProxySQL's PostgreSQL frontend rejects a spec-valid extended-protocol Bind message: when a client sends num_param_formats = 1 with num_params = 0, ProxySQL raises "Invalid param format count" and fails the exchange. Real PostgreSQL accepts this.

Wire-protocol background

Per the PostgreSQL protocol spec for Bind, the parameter-format-code count may be:

  • 0 — all parameters use text format,
  • 1 — the single format code applies to all parameters (valid regardless of the parameter count, including 0 — it is simply a no-op),
  • N — one code per parameter.

PostgreSQL's own exec_bind_message only errors when numPFormats > 1 && numPFormats != numParams.

Where

lib/PgSQL_Connection.cpp, stmt_execute_start() (~lines 1918–1928): the format-expansion branch is gated on param_values.size() > 1, so the param_formats.size()==1, param_values.size()==0 case falls through to the else if (param_formats.size() != param_values.size()) branch and is rejected.

Reproduction

Send Parse/Bind/Execute for a 0-parameter statement (e.g. SELECT 1) with a Bind carrying one format code (C=1, e.g. binary). Client libraries that always emit a single "apply-to-all" format code trip this.

Found by the SP-1 test suite (PR #5894): test/tap/tests/pgsql-datatype_matrix-t.cpp and test/tap/tests/pgsql-server_side_cursors-t.cpp had to work around it by sending an explicit empty paramFormats array (num_param_formats=0) for 0-param binds — see the in-test comments referencing this issue.

Expected

num_param_formats=1 accepted for any num_params, matching PostgreSQL: reject only numPFormats > 1 && numPFormats != numParams.

Suggested fix + regression test

Adjust the guard in stmt_execute_start() accordingly. A minimal regression test: 0-param Parse/Bind with a single format code must complete (once fixed, the workaround in the two SP-1 tests can also be reverted to bindStatementSingleFormat).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions