dbdpg icon indicating copy to clipboard operation
dbdpg copied to clipboard

last_insert_id failing for table name with double quotes

Open jboakye opened this issue 3 years ago • 6 comments

Good day folks.

Error: INSERT into " public.best!Tab le@Ever2$%^&()_+{}:'""?/.>,<~ 4" (" (id)$mipublic.lk'","""""''""""2--","not$%^&() _+{}:'""?/.>,<~nice","""""""""3'","""""''""""++") VALUES (?, ?, ?, ?, ?) DBD::Pg::db last_insert_id failed: Could not find the table " public.best!Tab le@Ever2$%^&*()_+{}\:'""?/.>,<~ `4" [for Statement " SELECT i.indisprimary, COALESCE( -- this takes the table name as text, not regclass pg_catalog.pg_get_serial_sequence( -- and pre-8.3 doesn't have a cast from regclass to text, -- and pre-9.3 doesn't have format, so do it the long way quote_ident(n.nspname) || '.' || quote_ident(c.relname), <>

The issue seems to be that since I have double quotes in the table name, I have to "double up" the double quotes for the insert statement but you folks may need to replace all "" in the table name to " before running your query. $table_name_for_query = $table_name; $table_name_for_query =~ s/["]{2}/"/g;

jboakye avatar Nov 10 '21 12:11 jboakye

perl: 5.26.1, Postgresql 13, latest version of DBD Pg

jboakye avatar Nov 10 '21 12:11 jboakye

Maybe In Pg.pm?: my $table_for_query = $table; $table_for_query =~ s/["]{2}/"/g; my @args = ($table_for_query);

jboakye avatar Nov 10 '21 13:11 jboakye

I made the change to my local copy of Pg.pm and that seems to have fixed it:

---snip my $query_table = $table; $query_table =~ s/["]{2}/"/g; my @args = ($query_table); my $schemawhere; if (length $schema) { # if given a schema, use that $schemawhere = 'n.nspname = ?'; push @args, $schema; } else { # otherwise it must be visible via the search path $schemawhere = 'pg_catalog.pg_table_is_visible(c.oid)'

-- snip

jboakye avatar Nov 10 '21 16:11 jboakye

diff --git a/Pg.pm b/Pg.pm index 2839aab..80ae1c1 100644 --- a/Pg.pm +++ b/Pg.pm @@ -351,7 +351,10 @@ use 5.008001; $dbh->set_err(1, 'last_insert_id needs at least a sequence or table name'); return undef; }

  •        my @args = ($table);
    
  •        #if table includes double quotes, it would be paired up at this point. we want to unpair it.
    
  •        my $table_for_query = $table;
    
  •        $table_for_query =~  s/["]{2}/"/g;
    
  •        my @args = ($table_for_query);
           my $schemawhere;
           if (length $schema) {
               # if given a schema, use that
    

I have a fix ready to go if I am able to open a pull request, I appreciate all of your work and I know you are busy. If I could get some sort of response that would be great as my current project is stalled. Thank you all so much.

jboakye avatar Nov 11 '21 02:11 jboakye

@jboakye : Your diff here was completely mangled because it wasn't inside triple backticks (```). I recommend opening a PR. I think the maintainer(s) would be able to evaluate your solution best that way.

esabol avatar Mar 01 '22 04:03 esabol

Not sure this is a bug - last_insert() should be passed the literal table name, not a doubled-up double quote version. I put a new test for that in t/03smethod.t - please take a look at that if you can.

5f83ebfb6b90138bb960d0c1cd9aa505beaaea41

turnstep avatar Mar 01 '22 16:03 turnstep

Closing this for now

turnstep avatar Aug 14 '23 19:08 turnstep