Thread

  1. [PATCH] psql: Allow connection string parameters as positional arguments

    Daymel Bonne Solís <daymelbonne@gmail.com> — 2025-12-18T20:23:46Z

    Hi hackers,
    
    I'd like to propose a small enhancement to psql that improves usability
    when working with connection services and other libpq connection parameters.
    
    Problem
    
    Currently, when users try to use connection string parameters like
    service=myservice as positional arguments to psql, the behavior is
    confusing. For example:
    
    psql service=production dbname=postgres -c "SELECT current_database()"
    
    This fails with:
    Password for user dbname=postgres:
    psql: error: password authentication failed for user "dbname=postgres"
    
    The issue is that psql interprets service=centraldb as the database name
    (first positional arg) and dbname=postgres as the username (second
    positional arg), treating them as literal strings rather than connection
    parameters.
    
    Use Case
    
    This is particularly inconvenient when working with pg_service.conf, where
    users define connection profiles but occasionally need to override specific
    parameters. Currently, the workaround requires quoting the entire
    connection string:
    
    # Current workaround (verbose)
    psql -d "service=centraldb dbname=postgres" -c "SELECT current_database()"
    
    # Desired syntax (intuitive)
    psql service=centraldb -d postgres -c "SELECT current_database()"
    
    The proposed syntax is more intuitive and aligns with how other tools
    handle similar parameter overrides.
    
    Solution
    
    This patch modifies psql to recognize positional arguments containing = as
    connection string parameters. These are collected into a connection string
    that serves as the base for the connection. Explicit options (-d, -h, -p,
    -U) override corresponding values.
    
    The implementation:
    - Adds a connstring field to struct adhoc_opts
    - Modifies parse_psql_options() to detect and collect key=value arguments
    - Updates the connection logic to merge connstring with explicit options
    
    Backward Compatibility
    
    This change is fully backward compatible:
    - Regular positional arguments (without =) continue to work as database
    name and username
    - Database names containing = are rare and can still be specified via -d
    "db=name"
    - All existing command-line patterns remain functional
    
    Examples
    
    # Use service with database override
    psql service=production -d postgres
    
    # Multiple connection parameters
    psql host=localhost port=5433 sslmode=require -d mydb
    
    # Mix key=value with regular positional arg
    psql host=localhost port=5433 mydb
    
    Testing
    
    The patch includes a new TAP test file (t/002_connstring.pl) with 17 test
    cases covering:
    - Basic key=value positional arguments
    - Override behavior with -d flag
    - Multiple key=value parameters
    - Mixed key=value and regular positional arguments
    - Parameter ordering variations
    
    All existing psql tests continue to pass.
    
    Patch attached.
    
    Feedback welcome!
    
    ---
    Best regards, Daymel Bonne