Skip to content

fix: correct PGOPTIONS parsing and search_path handling#768

Closed
b3b wants to merge 1 commit intosupabase:mainfrom
b3b:fix/pgoptions-parsing
Closed

fix: correct PGOPTIONS parsing and search_path handling#768
b3b wants to merge 1 commit intosupabase:mainfrom
b3b:fix/pgoptions-parsing

Conversation

@b3b
Copy link
Copy Markdown
Contributor

@b3b b3b commented Nov 1, 2025

What kind of change does this PR introduce?

Bug fix: improves PGOPTIONS parsing to correctly handle both --key=value and -c key=value syntax, prevent malformed tokens, and avoid leaking unintended parameters to Postgres.

What is the current behavior?

Supavisor currently parses PGOPTIONS using URI.decode_query, but PostgreSQL does not URI-encode connection options they are space-separated key=value pairs.

This causes several issues:

  • Only the first parameter is parsed
PGOPTIONS="--log_level=debug --search_path=custom" psql 'postgresql://...' -c "show search_path"
search_path   
-----------------
 "$user", public
(1 row)
  • Common -c key=value syntax is not supported
PGOPTIONS="-c search_path=custom" psql 'postgresql://...' -c "show search_path"
search_path   
-----------------
 "$user", public
(1 row)
  • When --search_path is first, following options are passed through
PGOPTIONS="--search_path=custom --work_mem=1234567" psql 'postgresql://...' -c "select name, setting from pg_settings where name in ('search_path','work_mem');"
    name     | setting 
-------------+---------
 search_path | custom
 work_mem    | 1234567
(2 rows)
PGOPTIONS='--search_path=custom -malformed' psql  'postgresql://...' -c "show search_path"
server closed the connection unexpectedly

Note

In this case, Supavisor repeatedly tries to reconnect and floods the logs with: [error] DbHandler: Error auth response ["SFATAL", "VFATAL", "C42601", "Minvalid command-line argument for server process: --search_path=custom", "HTry \"postgres --help\" for more information.", "Fpostgres.c", "L3931", "Rprocess_postgres_switches"]

Related issues

What is the new behavior?

  • Supports both --key=value and -c key=value forms.
  • Ignores malformed tokens safely and logs a warning.
  • Prevents unintended parameters from being forwarded to Postgres.
  • Passes recognized option values as-is to Postgres, preserving quotes and escapes

Additional context

Integration tests for this behavior are included in #770

Replaces the old URI.decode_query-based parser with a new
StartupOptions tokenizer that accurately parses the `options` field
from PostgreSQL startup packets.

- Prevents forwarding of extra options after `--search_path`
- Supports `--key=value,` `-c key=value` and `-ckey=value` forms
@v0idpwn
Copy link
Copy Markdown
Member

v0idpwn commented Feb 11, 2026

Incorporated this in #858 too, thank you!

@v0idpwn v0idpwn closed this Feb 11, 2026
v0idpwn added a commit that referenced this pull request Feb 11, 2026
- Fixes #854, a bug reported recently (a change in a Go library caused
it to start hitting this bug)
- Properly parses the options field in the startup message -- it was
just off since forever. This was implemented in #768 by @b3b but I
decided to give it a stab.
- Ensures we handle search_path correctly
- `log_level` is set on ClientHandler, but that's not very useful since
currently it can only be used to **decrease** the log level, not
increase (consequence of how process log level works in elixir)
- Other options continue being ignored, they are just parsed properly
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.

2 participants