pgloader icon indicating copy to clipboard operation
pgloader copied to clipboard

`PGUSER` used instead of `PGDATABASE`

Open infojunkie opened this issue 3 years ago • 3 comments

It would seem that env var PGUSER is used instead of PGDATABASE as the database name when no explicit database name is given in the connection string.

  • [x] pgloader --version
pgloader version "3.6.2c52da1"
compiled with SBCL 2.1.11.debian
  • [x] did you test a fresh compile from the source tree?

  • [x] did you search for other similar issues?

  • [x] how can I reproduce the bug?

  1. Export PGUSER, PGPASSWORD, PGHOST and PGDATABASE as per your connection settings. Make sure PGUSER and PGDATABASE are different.
  2. Use the following load script.
LOAD CSV
     FROM INLINE with encoding 'ascii'
     INTO postgresql:///
     TARGET TABLE jordane

     WITH truncate,
          fields terminated by '|',
          fields not enclosed,
          fields escaped by backslash-quote

      SET work_mem to '128MB',
          standard_conforming_strings to 'on'

   BEFORE LOAD DO
    $$ drop table if exists jordane; $$,
    $$ CREATE TABLE jordane
       (
         "NOM" character(20),
         "PRENOM" character(20)
       )
    $$;

BORDET|Jordane
BORDET|Audrey
LASTNAME|"opening quote
BONNIER|testprenombe~aucouptroplong
JOURDAIN|héhé
  • [x] pgloader output you obtain
FATAL error: Failed to connect to pgsql at "localhost" (port 5432) as user "<PGUSER>": Database error 3D000: database "<PGUSER>" does not exist
  • [x] data that is being loaded, if relevant

No data is being loaded

  • [x] How the data is different from what you expected, if relevant

I expect the PGDATABASE env var to be used as the target database instead of PGUSER.

infojunkie avatar Jul 08 '22 03:07 infojunkie

When I change https://github.com/dimitri/pgloader/blob/master/src/parsers/command-db-uri.lisp#L253 to

:name (getenv-default "PGDATABASE" user)

i.e. don't use dbname, the PGDATABASE value is used correctly. Why is dbname being populated with the value of PGUSER when it is given an empty string?

infojunkie avatar Jul 08 '22 04:07 infojunkie

I found that dbname comes into this block with the value "", instead of NIL, causing the (or dbname) condition to be true and hence the confusion.

I replaced this line with:

  :name (or (unless (or (null dbname) (equal dbname "")) dbname)
            (getenv-default "PGDATABASE" user))

and things work as expected.

This is the first time I write CL, so I'll let someone more qualified produce a fix with better code.

infojunkie avatar Jul 12 '22 04:07 infojunkie

I'd prefer

(if (plusp (length dbname))  ; works for NIL and "" the same
    dbname
    (getenv-default "PGDATABASE" user))

svantevonerichsen6906 avatar Jul 12 '22 09:07 svantevonerichsen6906