Hi,

for some maintenance script, I used a line like:

| my $s = $DB->selectcol_arrayref ("SELECT Column1 FROM Table WHERE NOT 
(Column2 = ANY(?::TEXT[]));", {}, ["abc", "def"]);

This worked perfectly, except when I started to add strings
with backslashes to the (Perl) array. Shortest non-working
example:

| my $DB = DBI->connect ('dbi:Pg:dbname=tim', undef, undef, { pg_enable_utf8 => 
1, PrintError => 0 }) or die (DBI->errstr ());
| my $TestOutput = $DB->selectcol_arrayref ('SELECT 
LENGTH(unnest(?::TEXT[]));', {}, ['abc', 'def', 'g\hi']) or die ($DB->errstr 
());
| $DB->disconnect () or die ($DB->errstr ());
| print Dumper $TestOutput;

gives:

| $VAR1 = [
|           3,
|           3,
|           5
|         ];

On PostgreSQL's side, there end up two backslashes. Appa-
rently, this is due to the cast as a scalar string doesn't
get mangled.

  Remembering the PG_BYTEA thing, I found PG_TEXTARRAY in
the manual. As there seems to be no way to bind_param () in
a selectcol_arrayref (), my first try was:

| my $st = $DB->prepare ('SELECT LENGTH(unnest(?));') or die ($DB->errstr ());
| $st->bind_param (1, undef, { pg_type => PG_TEXTARRAY }) or die ($DB->errstr 
());
| $st->execute (['abc', 'def', 'g\hi']) or die ($DB->errstr ());
| while (my @r = $st->fetchrow ())
| { print Dumper \...@r; }

which gives:

| ERROR:  function length(cstring) does not exist
| ZEILE 1: SELECT LENGTH(unnest($1));
|                 ^
| TIP:  No function matches the given name and argument types. You might need 
to add explicit type casts. at /var/tmp/escape-test.pl line 15.

So, another explicit cast:

| my $st = $DB->prepare ('SELECT LENGTH(unnest(?)::TEXT);') or die ($DB->errstr 
());

which gives:

| $VAR1 = [
|           3
|         ];
| $VAR1 = [
|           3
|         ];
| $VAR1 = [
|           5
|         ];

That was when I gave up and came here :-). Version informa-
tion: PostgreSQL 8.4.4, DBD::Pg 2.17.1, DBI 1.607,
Perl 5.10.0.

  So, my question is: How do I pass an array of strings with
backslashes as a parameter successfully?

Tim

Reply via email to