pg: Add prepared statement caching
The tests are not as thourough as I would like. There's many ways to mess this up. I was initially planning to drop the ref on the prepared statement immediately after executing the query, so that the $st object can be kept around for introspection without consuming excess resources. Unfortunately, PQcopyResult does not copy over information about bind parameters, so we need another way to keep that information alive. I ended up going for the simple solution: keep the ref on the prepared statement...
This commit is contained in:
parent
87d99e412b
commit
1f7e2de9a0
4 changed files with 190 additions and 10 deletions
|
|
@ -17,7 +17,7 @@ okerr FATAL => connect => qr/missing "=" after "invalid"/;
|
|||
|
||||
ok FU::Pg::lib_version() > 100000;
|
||||
|
||||
my $conn = FU::Pg->connect($ENV{FU_TEST_DB})->text;
|
||||
my $conn = FU::Pg->connect($ENV{FU_TEST_DB})->text->cache(0);
|
||||
$conn->_debug_trace(0);
|
||||
|
||||
is ref $conn, 'FU::Pg::conn';
|
||||
|
|
@ -325,6 +325,62 @@ subtest 'txn', sub {
|
|||
is $conn->q('SELECT count(*) FROM fupg_tst WHERE id = 3')->val, 0;
|
||||
};
|
||||
|
||||
{
|
||||
local $_ = 'x';
|
||||
my $st = $conn->q('SELECT $1', $_);
|
||||
$_ = 'y';
|
||||
is $st->val, 'x', 'shallow copy';
|
||||
}
|
||||
|
||||
{
|
||||
my $a = [1,2];
|
||||
my $st = $conn->q('SELECT $1::int[]', $a)->text(0);
|
||||
$a->[1] = 3;
|
||||
is_deeply $st->val, [1,3], 'not deep copy';
|
||||
}
|
||||
|
||||
subtest 'Prepared statement cache', sub {
|
||||
my $txn = $conn->cache_size(2)->txn->cache;
|
||||
my sub numexec($sql) {
|
||||
$txn->q('SELECT generic_plans + custom_plans FROM pg_prepared_statements WHERE statement = $1', $sql)->cache(0)->val
|
||||
}
|
||||
is $txn->q('SELECT 1')->val, 1;
|
||||
is numexec('SELECT 1'), 1;
|
||||
|
||||
my $sql = 'SELECT $1::int as a, $2::text as b';
|
||||
ok !defined numexec($sql);
|
||||
|
||||
my $params = $txn->q($sql)->param_types;
|
||||
is_deeply $params, [23, 25];
|
||||
is numexec($sql), 0;
|
||||
my $cparams = $txn->q($sql)->param_types;
|
||||
is_deeply $cparams, $params;
|
||||
|
||||
my $cols = $txn->q($sql)->columns;
|
||||
is_deeply $cols, [{ name => 'a', oid => 23 }, { name => 'b', oid => 25 }];
|
||||
my $ccols = $txn->q($sql)->columns;
|
||||
is_deeply $ccols, $cols;
|
||||
|
||||
$txn->q($sql, 0, '')->exec;
|
||||
is numexec($sql), 1;
|
||||
$txn->q($sql, 0, '')->exec;
|
||||
is numexec($sql), 2;
|
||||
|
||||
is numexec('SELECT 1'), 1;
|
||||
$txn->q('SELECT 2')->exec;
|
||||
ok !defined numexec('SELECT 1');
|
||||
is numexec('SELECT 2'), 1;
|
||||
|
||||
$conn->cache_size(1);
|
||||
ok !defined numexec('SELECT 1');
|
||||
ok !defined numexec($sql);
|
||||
is numexec('SELECT 2'), 1;
|
||||
|
||||
$conn->cache_size(0);
|
||||
ok !defined numexec($sql);
|
||||
ok !defined numexec('SELECT 2');
|
||||
};
|
||||
|
||||
{
|
||||
my $st = $conn->q("SELECT 1");
|
||||
undef $conn; # statement keeps the connection alive
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue