1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
#!perl -w
# Test of placeholders
use Test::More;
use DBI;
use strict;
$|=1;
if (defined $ENV{DBI_DSN}) {
plan tests => 20;
} else {
plan skip_all => 'Cannot run test unless DBI_DSN is defined. See the README file';
}
my $dbh = DBI->connect($ENV{DBI_DSN}, $ENV{DBI_USER}, $ENV{DBI_PASS},
{RaiseError => 1, PrintError => 0, AutoCommit => 0});
ok( defined $dbh, 'Connect to database for placeholder testing');
if (DBD::Pg::_pg_use_catalog($dbh)) {
$dbh->do("SET search_path TO " . $dbh->quote_identifier
(exists $ENV{DBD_SCHEMA} ? $ENV{DBD_SCHEMA} : 'public'));
}
my ($pglibversion,$pgversion) = ($dbh->{pg_lib_version},$dbh->{pg_server_version});
if ($pgversion >= 80100) {
$dbh->do("SET escape_string_warning = false");
}
# Make sure that quoting works properly.
my $quo = $dbh->quote("\\'?:");
is( $quo, "'\\\\''?:'", "Properly quoted");
# Make sure that quoting works with a function call.
# It has to be in this function, otherwise it doesn't fail the
# way described in https://rt.cpan.org/Ticket/Display.html?id=4996.
sub checkquote {
my $str = shift;
is( $dbh->quote(substr($str, 0, 10)), "'$str'", "First function quote");
}
checkquote('one');
checkquote('two');
checkquote('three');
checkquote('four');
my $sth = $dbh->prepare(qq{INSERT INTO dbd_pg_test (id,pname) VALUES (?, $quo)});
$sth->execute(100);
my $sql = "SELECT pname FROM dbd_pg_test WHERE pname = $quo";
$sth = $dbh->prepare($sql);
$sth->execute();
my ($retr) = $sth->fetchrow_array();
ok( (defined($retr) && $retr eq "\\'?:"), "fetch");
eval {
$sth = $dbh->prepare($sql);
$sth->execute('foo');
};
ok( $@, 'execute with one bind param where none expected');
$sql = "SELECT pname FROM dbd_pg_test WHERE pname = ?";
$sth = $dbh->prepare($sql);
$sth->execute("\\'?:");
($retr) = $sth->fetchrow_array();
ok( (defined($retr) && $retr eq "\\'?:"), 'execute with ? placeholder');
$sql = "SELECT pname FROM dbd_pg_test WHERE pname = :1";
$sth = $dbh->prepare($sql);
$sth->bind_param(":1", "\\'?:");
$sth->execute();
($retr) = $sth->fetchrow_array();
ok( (defined($retr) && $retr eq "\\'?:"), 'execute with :1 placeholder');
$sql = q{SELECT pname FROM dbd_pg_test WHERE pname = $1 AND pname <> 'foo'};
$sth = $dbh->prepare($sql);
$sth->execute("\\'?:");
($retr) = $sth->fetchrow_array();
ok( (defined($retr) && $retr eq "\\'?:"), 'execute with $1 placeholder');
$sql = "SELECT pname FROM dbd_pg_test WHERE pname = '?'";
eval {
$sth = $dbh->prepare($sql);
$sth->execute('foo');
};
ok( $@, 'execute with quoted ?');
$sql = "SELECT pname FROM dbd_pg_test WHERE pname = ':1'";
eval {
$sth = $dbh->prepare($sql);
$sth->execute('foo');
};
ok( $@, 'execute with quoted :1');
$sql = "SELECT pname FROM dbd_pg_test WHERE pname = '\\\\' AND pname = '?'";
$sth = $dbh->prepare($sql);
eval {
## XX ???
local $dbh->{PrintError} = 0;
local $sth->{PrintError} = 0;
$sth->execute('foo');
};
ok( $@, 'execute with quoted ?');
## Test large number of placeholders
$sql = 'SELECT 1 FROM dbd_pg_test WHERE id IN (' . '?,' x 300 . "?)";
my @args = map { $_ } (1..301);
$sth = $dbh->prepare($sql);
my $count = $sth->execute(@args);
$sth->finish();
ok( $count >= 1, 'prepare with large number of parameters works');
$sth->finish();
## Test our parsing of backslashes
$sth = $dbh->prepare("SELECT '\\'?'");
eval {
$sth->execute();
};
ok( !$@, 'prepare with backslashes inside quotes works');
$sth->finish();
## Test do() with placeholders, both DML and non-DML
eval {
$dbh->do(q{SET search_path TO ?}, undef, 'public');
};
ok( !$@, 'do() called with non-DML placeholder works');
eval {
$dbh->do(q{SELECT ?::text}, undef, 'public');
};
ok( !$@, 'do() called with non-DML placeholder works');
## Test a non-DML placeholder
eval {
$sth = $dbh->prepare(qq{SET search_path TO ?});
$sth->execute('public');
};
ok( !$@, 'prepare/execute iwth non-DML placeholder works');
$dbh->rollback();
ok( $dbh->disconnect(), 'Disconnect from database');
|