Skip to content

Fix malformed Bind packets when client provides a single parameter format#5282

Merged
renecannao merged 3 commits intov3.0from
v3.0_bind-format-issue-5273-fix
Jan 12, 2026
Merged

Fix malformed Bind packets when client provides a single parameter format#5282
renecannao merged 3 commits intov3.0from
v3.0_bind-format-issue-5273-fix

Conversation

@rahim-kanji
Copy link
Collaborator

@rahim-kanji rahim-kanji commented Jan 8, 2026

Background

In the PostgreSQL extended query protocol, the Bind message supports the
following semantics for parameter formats:

  • num_param_formats = 0: all parameters use the default text format
  • num_param_formats = 1: a single format applies to all parameters
  • num_param_formats = num_params: each parameter has an explicit format

Any other combination is invalid.

While PostgreSQL correctly applies the single provided format to all parameters,
ProxySQL previously did not replicate this behavior.

Issue

When a client sent a Bind message with:

  • num_param_formats = 1
  • num_params > 1

ProxySQL forwarded uninitialized (garbage) values for the remaining parameter
formats (libpq has a limitation where it expects a parameter format entry for each
parameter
). This resulted in malformed Bind packets and protocol errors.

Fix

This PR updates ProxySQL’s Bind handling to match PostgreSQL behavior:

  • When exactly one parameter format is provided, ProxySQL now applies that
    format to all parameters.

This prevents malformed packets and ensures compatibility with libpq and compliance with the PostgreSQL specification.

Impact

  • Aligns ProxySQL with PostgreSQL extended query protocol semantics
  • Prevents malformed Bind packets

No behavior change occurs for valid cases where all parameter formats are
explicitly provided.

Closes #5273

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced parameter format handling for PostgreSQL prepared statements, now supporting default text, single-format, and per-parameter format specifications.
  • Tests

    • Added comprehensive regression test suite for PostgreSQL parameter format binding, covering text/binary formats, mixed formats, and NULL parameter scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

…ovided

PostgreSQL allows a Bind message to specify a single parameter format
(num_param_formats = 1), which applies to all parameters.

libpq, however, always expects a format entry per parameter and previously
sent uninitialized values for the remaining parameters when only one format
was specified. This caused ProxySQL to forward malformed Bind packets to
backend.

ProxySQL now detects this case and propagates the single provided parameter
format to all parameters, matching PostgreSQL semantics.
@rahim-kanji rahim-kanji requested a review from Copilot January 8, 2026 09:56
@gemini-code-assist
Copy link

Summary of Changes

Hello @rahim-kanji, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a critical bug in ProxySQL's PostgreSQL extended query protocol implementation. It specifically addresses an issue where Bind messages specifying a single format for multiple parameters were mishandled, resulting in malformed packets and protocol errors. The changes bring ProxySQL's behavior in line with the PostgreSQL specification and improve compatibility with libpq clients, ensuring robust and correct parameter format processing.

Highlights

  • PostgreSQL Bind Message Protocol Alignment: ProxySQL's handling of the PostgreSQL extended query protocol's Bind message has been updated to correctly interpret cases where a single parameter format is provided for multiple parameters. Previously, this led to malformed packets and protocol errors.
  • Parameter Format Expansion Logic: The core fix involves modifying the PgSQL_Connection::stmt_execute_start method to expand a single provided parameter format across all parameters when num_param_formats = 1 and num_params > 1, ensuring compliance with PostgreSQL's specification.
  • libpq Compatibility Improvement: The PQsendQueryPrepared call now correctly passes nullptr for parameter formats when num_param_formats = 0, aligning with libpq's expectation for all-text parameters and preventing potential issues.
  • Comprehensive Test Coverage: New test cases have been added, including a dedicated test file pgsql-reg_test_5273_bind_parameter_format-t.cpp, to thoroughly validate the fix across various scenarios such as zero, single, and mixed parameter formats, as well as INSERT statements and NULL parameter handling.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively addresses a bug in handling PostgreSQL Bind packets where a single parameter format was not being correctly applied to all parameters. The core logic change in PgSQL_Connection.cpp is sound and correctly implements the protocol specification by expanding the format list. The accompanying new regression test is comprehensive and covers the fix well. I have a few minor suggestions to improve code style and maintainability in both the application and test code.

test_null_parameter_handling();

return exit_status();
} No newline at end of file

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The file does not end with a newline character. It's a common convention and good practice for text files to end with a newline to ensure compatibility with various tools and to follow POSIX standards.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a protocol compliance issue in ProxySQL's handling of PostgreSQL BIND messages. When a client provides a single parameter format (num_param_formats=1) for multiple parameters, ProxySQL previously forwarded uninitialized values, resulting in malformed packets. The fix ensures ProxySQL correctly expands the single format to all parameters before forwarding to libpq, which expects an explicit format for each parameter.

  • Adds format normalization logic in PgSQL_Connection.cpp to expand single format to all parameters
  • Introduces comprehensive test suite with 7 test cases covering all protocol scenarios
  • Adds test client helpers (bindStatementEx and bindStatementSingleFormat) for explicit format control

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
lib/PgSQL_Connection.cpp Implements the core fix: expands single parameter format to all parameters and validates format counts
test/tap/tests/pg_lite_client.h Adds new bind method signatures for explicit format control in tests
test/tap/tests/pg_lite_client.cpp Implements new bind methods and updates existing bindStatement to optimize format encoding
test/tap/tests/pgsql-reg_test_5273_bind_parameter_format-t.cpp New comprehensive test suite covering all protocol scenarios
test/tap/tests/pgsql-extended_query_protocol_test-t.cpp Moves plan() call before cl.getEnv() for proper test structure
test/tap/tests/Makefile Adds build target for new test

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 9, 2026

@renecannao renecannao added this to the Release 3.0.5 milestone Jan 11, 2026
@renecannao
Copy link
Contributor

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Jan 11, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link

coderabbitai bot commented Jan 11, 2026

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

📥 Commits

Reviewing files that changed from the base of the PR and between 4f675ed and b0ce03c.

📒 Files selected for processing (7)
  • lib/PgSQL_Connection.cpp
  • test/tap/groups/groups.json
  • test/tap/tests/Makefile
  • test/tap/tests/pg_lite_client.cpp
  • test/tap/tests/pg_lite_client.h
  • test/tap/tests/pgsql-extended_query_protocol_test-t.cpp
  • test/tap/tests/pgsql-reg_test_5273_bind_parameter_format-t.cpp
 ______________________________________________________
< Multiplying to perform multi-threaded bug detection. >
 ------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).

Tip

You can validate your CodeRabbit configuration file in your editor.

If your editor has YAML language server, you can enable auto-completion and validation by adding # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json at the top of your CodeRabbit configuration file.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@renecannao renecannao merged commit c6ed5b9 into v3.0 Jan 12, 2026
150 of 154 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PostgreSQL extended query protocol returns "unsupported format code"

3 participants