Pg: Support type override configuration
This commit is contained in:
parent
3662931fc2
commit
327fd9ea50
5 changed files with 215 additions and 34 deletions
|
|
@ -14,7 +14,31 @@ is_deeply $conn->Q('SELECT 1', IN([1,2,3]))->param_types, [1007];
|
|||
is $conn->Q('SELECT 1', IN([1,2,3]))->val, 1;
|
||||
|
||||
ok !eval { $conn->q('SELECT $1::aclitem', '')->exec; 1 };
|
||||
like $@, qr/Unable to send or receive/;
|
||||
like $@, qr/Unable to send type/;
|
||||
|
||||
|
||||
$conn->set_type(int4 => recv => 'bytea');
|
||||
is $conn->q('SELECT 5::int4')->val, "\0\0\0\5";
|
||||
is_deeply $conn->q('SELECT ARRAY[5::int4]')->val, ["\0\0\0\5"];
|
||||
|
||||
$conn->set_type(int4 => send => 'bytea');
|
||||
is $conn->q('SELECT $1::int4', "\0\0\0\5")->val, 5;
|
||||
is_deeply $conn->q('SELECT $1::int4[]', ["\0\0\0\5"])->val, [5];
|
||||
|
||||
$conn->set_type(int4 => 'int2');
|
||||
ok !eval { $conn->q('SELECT 5::int4')->val };
|
||||
like $@, qr/Error parsing value/;
|
||||
ok !eval { $conn->q('SELECT $1::int4', 5)->val };
|
||||
like $@, qr/insufficient data left in message/;
|
||||
|
||||
$conn->set_type(int4 => undef);
|
||||
is $conn->q('SELECT 5::int4')->val, 5;
|
||||
|
||||
ok !eval { $conn->set_type(int4 => 1007); };
|
||||
like $@, qr/Cannot set a type to array/;
|
||||
|
||||
ok !eval { $conn->set_type(int4 => 1); };
|
||||
like $@, qr/No builtin type found/;
|
||||
|
||||
{
|
||||
my $txn = $conn->txn;
|
||||
|
|
@ -22,29 +46,29 @@ like $@, qr/Unable to send or receive/;
|
|||
is $txn->Q('SELECT 1', IN([1,2,3]))->val, 1;
|
||||
|
||||
$txn->exec(<<~_);
|
||||
CREATE TYPE fupg_test_enum AS ENUM('a', 'b', 'ccccccccccccccccccc');
|
||||
CREATE DOMAIN fupg_test_domain AS fupg_test_enum CHECK(value IN('a','b'));
|
||||
CREATE TYPE fupg_test_enum AS ENUM('aa', 'bb', 'ccccccccccccccccccc');
|
||||
CREATE DOMAIN fupg_test_domain AS fupg_test_enum CHECK(value IN('aa','bb'));
|
||||
CREATE TYPE fupg_test_record AS (
|
||||
a int,
|
||||
aenum fupg_test_enum[],
|
||||
domain fupg_test_domain
|
||||
);
|
||||
_
|
||||
is $txn->q("SELECT 'a'::fupg_test_enum")->val, 'a';
|
||||
is $txn->q("SELECT 'aa'::fupg_test_enum")->val, 'aa';
|
||||
is $txn->q('SELECT $1::fupg_test_enum', 'ccccccccccccccccccc')->val, 'ccccccccccccccccccc';
|
||||
|
||||
is_deeply $txn->q("SELECT '{a,b,null}'::fupg_test_enum[]")->val, ['a','b',undef];
|
||||
is $txn->q('SELECT $1::fupg_test_enum[]', ['a','b',undef])->text_results->val, '{a,b,NULL}';
|
||||
is_deeply $txn->q("SELECT '{aa,bb,null}'::fupg_test_enum[]")->val, ['aa','bb',undef];
|
||||
is $txn->q('SELECT $1::fupg_test_enum[]', ['aa','bb',undef])->text_results->val, '{aa,bb,NULL}';
|
||||
|
||||
is $txn->q("SELECT 'a'::fupg_test_domain")->val, 'a';
|
||||
is $txn->q('SELECT $1::fupg_test_domain', 'b')->val, 'b';
|
||||
is $txn->q("SELECT 'aa'::fupg_test_domain")->val, 'aa';
|
||||
is $txn->q('SELECT $1::fupg_test_domain', 'bb')->val, 'bb';
|
||||
|
||||
is_deeply $txn->q("SELECT '{a,b,null}'::fupg_test_domain[]")->val, ['a','b',undef];
|
||||
is $txn->q('SELECT $1::fupg_test_domain[]', ['a','b',undef])->text_results->val, '{a,b,NULL}';
|
||||
is_deeply $txn->q("SELECT '{aa,bb,null}'::fupg_test_domain[]")->val, ['aa','bb',undef];
|
||||
is $txn->q('SELECT $1::fupg_test_domain[]', ['aa','bb',undef])->text_results->val, '{aa,bb,NULL}';
|
||||
|
||||
my $val = { a => undef, aenum => ['a','b'], domain => 'a' };
|
||||
is_deeply $txn->q("SELECT '(,\"{a,b}\",a)'::fupg_test_record")->val, $val;
|
||||
is $txn->q('SELECT $1::fupg_test_record', $val)->text_results->val, '(,"{a,b}",a)';
|
||||
my $val = { a => undef, aenum => ['aa','bb'], domain => 'aa' };
|
||||
is_deeply $txn->q("SELECT '(,\"{aa,bb}\",aa)'::fupg_test_record")->val, $val;
|
||||
is $txn->q('SELECT $1::fupg_test_record', $val)->text_results->val, '(,"{aa,bb}",aa)';
|
||||
|
||||
$txn->exec(<<~_);
|
||||
CREATE TEMPORARY TABLE fupg_test_table (
|
||||
|
|
@ -53,15 +77,29 @@ like $@, qr/Unable to send or receive/;
|
|||
);
|
||||
_
|
||||
|
||||
is_deeply $txn->q(q{SELECT '{"(\"(2,{},b)\",)","(\"(,,)\",b)"}'::fupg_test_table[]})->val, [
|
||||
{ rec => { a => 2, aenum => [], domain => 'b' }, dom => undef },
|
||||
{ rec => { a => undef, aenum => undef, domain => undef }, dom => 'b' },
|
||||
is_deeply $txn->q(q{SELECT '{"(\"(2,{},bb)\",)","(\"(,,)\",bb)"}'::fupg_test_table[]})->val, [
|
||||
{ rec => { a => 2, aenum => [], domain => 'bb' }, dom => undef },
|
||||
{ rec => { a => undef, aenum => undef, domain => undef }, dom => 'bb' },
|
||||
];
|
||||
|
||||
is $txn->q('SELECT $1::fupg_test_table[]', [
|
||||
{ rec => { a => 2, aenum => [], domain => 'b' }, dom => undef },
|
||||
{ rec => {}, dom => 'b', extra => 1 },
|
||||
])->text_results->val, '{"(\"(2,{},b)\",)","(\"(,,)\",b)"}';
|
||||
{ rec => { a => 2, aenum => [], domain => 'bb' }, dom => undef },
|
||||
{ rec => {}, dom => 'bb', extra => 1 },
|
||||
])->text_results->val, '{"(\"(2,{},bb)\",)","(\"(,,)\",bb)"}';
|
||||
|
||||
# Wonky Postgres behavior: selecting a domain directly actually returns the
|
||||
# underlying type, but going through an array does work.
|
||||
$conn->set_type(fupg_test_domain => 21);
|
||||
is_deeply $txn->q("SELECT ARRAY['aa'::fupg_test_domain]")->val, [0x6161];
|
||||
|
||||
# Bind param type doesn't match column type, argh.
|
||||
is $txn->q('SELECT $1::fupg_test_domain', 0x6161)->val, 'aa';
|
||||
|
||||
# Same for selecting from a table :(
|
||||
$txn->exec("INSERT INTO fupg_test_table VALUES (NULL, 'bb')");
|
||||
is $txn->q("SELECT dom FROM fupg_test_table")->val, 'bb';
|
||||
$conn->set_type(fupg_test_enum => 21);
|
||||
is $txn->q("SELECT dom FROM fupg_test_table")->val, 0x6262;
|
||||
}
|
||||
|
||||
done_testing;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue