Author: turnstep
Date: Tue Jul 21 07:09:07 2009
New Revision: 13093
Modified:
DBD-Pg/trunk/t/12placeholders.t
Log:
Move geom quoting tests up, to prevent search_path problems.
Modified: DBD-Pg/trunk/t/12placeholders.t
==============================================================================
--- DBD-Pg/trunk/t/12placeholders.t (original)
+++ DBD-Pg/trunk/t/12placeholders.t Tue Jul 21 07:09:07 2009
@@ -141,575 +141,575 @@
my $expected = $backslash eq 'off' ? qr{unsafe} : qr{};
like ($@, $expected, $t);
-$t='Calling do() with non-DML placeholder works';
-$sth->finish();
-$dbh->commit();
-eval {
- $dbh->do(q{SET search_path TO ?}, undef, 'pg_catalog');
-};
-is ($@, q{}, $t);
+## Test quoting of geometric types
-$t='Calling do() with DML placeholder works';
-$dbh->commit();
-eval {
- $dbh->do(q{SELECT ?::text}, undef, 'public');
-};
-is ($@, q{}, $t);
+my @geotypes = qw/point line lseg box path polygon circle/;
-$t='Calling do() with invalid crowded placeholders fails cleanly';
-$dbh->commit();
-eval {
- $dbh->do(q{SELECT ??}, undef, 'public', 'error');
-};
-is($dbh->state, '42601', $t);
+$dbh->do("SET search_path TO DEFAULT");
+eval { $dbh->do("DROP TABLE dbd_pg_test_geom"); }; $dbh->commit();
-$t='Prepare/execute with non-DML placeholder works';
+$SQL = 'CREATE TABLE dbd_pg_test_geom (';
+for my $type (@geotypes) {
+ $SQL .= "x$type $type,";
+}
+$SQL =~ s/,$/)/;
+$dbh->do($SQL);
$dbh->commit();
-eval {
- $sth = $dbh->prepare(q{SET search_path TO ?});
- $sth->execute('pg_catalog');
-};
-is ($@, q{}, $t);
-$t='Prepare/execute does not allow geometric operators';
-$dbh->commit();
-eval {
- $sth = $dbh->prepare(q{SELECT ?- lseg '(1,0),(1,1)'});
- $sth->execute();
-};
-like ($@, qr{unbound placeholder}, $t);
+my %typemap = (
+ point => PG_POINT,
+ line => PG_LINE,
+ lseg => PG_LSEG,
+ box => PG_BOX,
+ path => PG_PATH,
+ polygon => PG_POLYGON,
+ circle => PG_CIRCLE,
+);
-$t='Prepare/execute allows geometric operator ?- when dollaronly is set';
-$dbh->commit();
-$dbh->{pg_placeholder_dollaronly} = 1;
-eval {
- $sth = $dbh->prepare(q{SELECT ?- lseg '(1,0),(1,1)'});
- $sth->execute();
- $sth->finish();
-};
-is ($@, q{}, $t);
+my $testdata = q{
+point datatype integers
+12,34
+'12,34'
+(12,34)
-$t='Prepare/execute allows geometric operator ?# when dollaronly set';
-$dbh->commit();
-eval {
- $sth = $dbh->prepare(q{SELECT lseg'(1,0),(1,1)' ?# lseg '(2,3),(4,5)'});
- $sth->execute();
- $sth->finish();
-};
-is ($@, q{}, $t);
+point datatype floating point numbers
+1.34,667
+'1.34,667'
+(1.34,667)
-$t=q{Value of placeholder_dollaronly can be retrieved};
-is ($dbh->{pg_placeholder_dollaronly}, 1, $t);
+point datatype exponential numbers
+1e34,9E4
+'1e34,9E4'
+(1e+34,90000)
-$t=q{Prepare/execute does not allow use of raw ? and :foo forms};
-$dbh->{pg_placeholder_dollaronly} = 0;
-eval {
- $sth = $dbh->prepare(q{SELECT uno ?: dos ? tres :foo bar $1});
- $sth->execute();
- $sth->finish();
-};
-like ($@, qr{mix placeholder}, $t);
+point datatype plus and minus signs
+1e+34,-.45
+'1e+34,-.45'
+(1e+34,-0.45)
-$t='Prepare/execute allows use of raw ? and :foo forms when dollaronly set';
-$dbh->{pg_placeholder_dollaronly} = 1;
-eval {
- $sth = $dbh->prepare(q{SELECT uno ?: dos ? tres :foo bar $1},
{pg_placeholder_dollaronly => 1});
- $sth->{pg_placeholder_dollaronly} = 1;
- $sth->execute();
- $sth->finish();
-};
-like ($@, qr{unbound placeholder}, $t);
+point datatype invalid number
+123,abc
+ERROR: Invalid input for geometric type
+ERROR: any
-$t='Prepare works with pg_placeholder_dollaronly';
-$dbh->{pg_placeholder_dollaronly} = 0;
-eval {
- $sth = $dbh->prepare(q{SELECT uno ?: dos ? tres :foo bar $1},
{pg_placeholder_dollaronly => 1});
- $sth->execute();
- $sth->finish();
-};
-like ($@, qr{unbound placeholder}, $t);
+point datatype invalid format
+123
+'123'
+ERROR: any
-$t='Prepare works with identical named placeholders';
-eval {
- $sth = $dbh->prepare(q{SELECT :row, :row, :row, :yourboat});
- $sth->finish();
-};
-is ($@, q{}, $t);
+point datatype invalid format
+123,456,789
+'123,456,789'
+ERROR: any
-$t='Prepare works with placeholders after double slashes';
-eval {
- $dbh->do(q{CREATE OPERATOR // ( PROCEDURE=bit, LEFTARG=int,
RIGHTARG=int )});
- $sth = $dbh->prepare(q{SELECT ? // ?});
- $sth->execute(1,2);
- $sth->finish();
-};
-is ($@, q{}, $t);
+point datatype invalid format
+<(2,4),6>
+ERROR: Invalid input for geometric type
+ERROR: any
-$t='Dollar quotes starting with a number are not treated as valid identifiers';
-eval {
- $sth = $dbh->prepare(q{SELECT $123$ $123$});
- $sth->execute(1);
- $sth->finish();
-};
-like ($@, qr{Invalid placeholders}, $t);
+point datatype invalid format
+[(1,2)]
+ERROR: Invalid input for geometric type
+ERROR: any
-$t='Dollar quotes with invalid characters are not parsed as identifiers';
-for my $char (qw!+ / : @ [ `!) {
- eval {
- $sth = $dbh->prepare(qq{SELECT \$abc${char}\$ 123
\$abc${char}\$});
- $sth->execute();
- $sth->finish();
- };
- like ($@, qr{syntax error}, $t);
-}
+line datatype integers
+12,34
+'12,34'
+ERROR: not yet implemented
-$t='Dollar quotes with valid characters are parsed as identifiers';
-$dbh->rollback();
-for my $char (qw{0 9 A Z a z}) {
- eval {
- $sth = $dbh->prepare(qq{SELECT \$abc${char}\$ 123
\$abc${char}\$});
- $sth->execute();
- $sth->finish();
- };
- is ($@, q{}, $t);
-}
+line datatype floating point numbers
+1.34,667
+'1.34,667'
+ERROR: not yet implemented
-SKIP: {
- skip 'Cannot run backslash_quote tet on Postgres < 8.2', 1 if
$pgversion < 80200;
+line datatype exponential numbers
+1e34,9E4
+'1e34,9E4'
+ERROR: not yet implemented
- $t='Backslash quoting inside double quotes is parsed correctly';
- $dbh->do(q{SET backslash_quote = 'on'});
- $dbh->commit();
- eval {
- $sth = $dbh->prepare(q{SELECT * FROM "\" WHERE a=?});
- $sth->execute(1);
- $sth->finish();
- };
- like ($@, qr{relation ".*" does not exist}, $t);
-}
+line datatype plus and minus signs
+1e+34,-.45
+'1e+34,-.45'
+ERROR: not yet implemented
-$dbh->rollback();
+line datatype invalid number
+123,abc
+ERROR: Invalid input for geometric type
+ERROR: not yet implemented
-SKIP: {
- skip 'Cannot adjust standard_conforming_strings for testing on this
version of Postgres', 2 if $pgversion < 80200;
- $t='Backslash quoting inside single quotes is parsed correctly with
standard_conforming_strings off';
- eval {
- $dbh->do(q{SET standard_conforming_strings = 'off'});
- $sth = $dbh->prepare(q{SELECT '\', ?});
- $sth->execute();
- $sth->finish();
- };
- like ($@, qr{unterminated quoted string}, $t);
- $dbh->rollback();
- $t='Backslash quoting inside single quotes is parsed correctly with
standard_conforming_strings on';
- eval {
- $dbh->do(q{SET standard_conforming_strings = 'on'});
- $sth = $dbh->prepare(q{SELECT '\', ?::int});
- $sth->execute(1);
- $sth->finish();
- };
- is ($@, q{}, $t);
-}
+lseg datatype invalid format
+12,34
+'12,34'
+ERROR: any
+lseg datatype integers
+(12,34),(56,78)
+'(12,34),(56,78)'
+[(12,34),(56,78)]
-$t='Valid integer works when quoting with SQL_INTEGER';
-my $val;
-$val = $dbh->quote('123', SQL_INTEGER);
-is ($val, 123, $t);
+lseg datatype floating point and exponential numbers
+(1.2,3.4),(5e3,7E1)
+'(1.2,3.4),(5e3,7E1)'
+[(1.2,3.4),(5000,70)]
-$t='Invalid integer fails to pass through when quoting with SQL_INTEGER';
-$val = -1;
-eval {
- $val = $dbh->quote('123abc', SQL_INTEGER);
-};
-like ($@, qr{Invalid integer}, $t);
-is($val, -1, $t);
-my $prefix = 'Valid float value works when quoting with SQL_FLOAT';
-for my $float ('123','0.00','0.234','23.31562',
'1.23e04','6.54e+02','4e-3','NaN','Infinity','-infinity') {
- $t = "$prefix (value=$float)";
- $val = -1;
- eval { $val = $dbh->quote($float, SQL_FLOAT); };
- is ($@, q{}, $t);
- is ($val, $float, $t);
+box datatype invalid format
+12,34
+'12,34'
+ERROR: any
- next unless $float =~ /\w/;
+box datatype integers
+(12,34),(56,78)
+'(12,34),(56,78)'
+(56,78),(12,34)
- my $lcfloat = lc $float;
- $t = "$prefix (value=$lcfloat)";
- $val = -1;
- eval { $val = $dbh->quote($lcfloat, SQL_FLOAT); };
- is ($@, q{}, $t);
- is ($val, $lcfloat, $t);
+box datatype floating point and exponential numbers
+(1.2,3.4),(5e3,7E1)
+'(1.2,3.4),(5e3,7E1)'
+(5000,70),(1.2,3.4)
- my $ucfloat = uc $float;
- $t = "$prefix (value=$ucfloat)";
- $val = -1;
- eval { $val = $dbh->quote($ucfloat, SQL_FLOAT); };
- is ($@, q{}, $t);
- is ($val, $ucfloat, $t);
-}
-$prefix = 'Invalid float value fails when quoting with SQL_FLOAT';
-for my $float ('3abc','123abc','','123e+04e+34','NaNum','-infinitee') {
- $t = "$prefix (value=$float)";
- $val = -1;
- eval { $val = $dbh->quote($float, SQL_FLOAT); };
- like ($@, qr{Invalid number}, $t);
- is ($val, -1, $t);
-}
+path datatype invalid format
+12,34
+'12,34'
+ERROR: any
-$dbh->rollback();
+path datatype integers
+(12,34),(56,78)
+'(12,34),(56,78)'
+((12,34),(56,78))
-## Test placeholders plus binding
-$t='Bound placeholders enforce data types when not using server side prepares';
-$dbh->trace(0);
-$dbh->{pg_server_prepare} = 0;
-$sth = $dbh->prepare('SELECT (1+?+?)::integer');
-$sth->bind_param(1, 1, SQL_INTEGER);
-eval {
- $sth->execute('10foo',20);
-};
-like ($@, qr{Invalid integer}, 'Invalid integer test 2');
+path datatype floating point and exponential numbers
+(1.2,3.4),(5e3,7E1)
+'(1.2,3.4),(5e3,7E1)'
+((1.2,3.4),(5000,70))
-## Test quoting of the "name" type
-$prefix = q{The 'name' data type does correct quoting};
+path datatype alternate bracket format
+[(1.2,3.4),(5e3,7E1)]
+'[(1.2,3.4),(5e3,7E1)]'
+[(1.2,3.4),(5000,70)]
-for my $word (qw/User user USER trigger Trigger/) {
- $t = qq{$prefix for the word "$word"};
- my $got = $dbh->quote($word, { pg_type => PG_NAME });
- $expected = qq{"$word"};
- is($got, $expected, $t);
-}
+path datatype many elements
+(1.2,3.4),(5,6),(7,8),(-9,10)
+'(1.2,3.4),(5,6),(7,8),(-9,10)'
+((1.2,3.4),(5,6),(7,8),(-9,10))
-for my $word (qw/auser userz user-user/) {
- $t = qq{$prefix for the word "$word"};
- my $got = $dbh->quote($word, { pg_type => PG_NAME });
- $expected = qq{$word};
- is($got, $expected, $t);
-}
+path datatype fails with braces
+{(1,2),(3,4)}
+ERROR: Invalid input for path type
+ERROR: any
-## Test quoting of booleans
-my %booltest = (
-undef => 'NULL',
-'t' => 'TRUE',
-'T' => 'TRUE',
-'true' => 'TRUE',
-'TRUE' => 'TRUE',
-1 => 'TRUE',
-01 => 'TRUE',
-'1' => 'TRUE',
-'0E0' => 'TRUE',
-'0e0' => 'TRUE',
-'0 but true' => 'TRUE',
-'0 BUT TRUE' => 'TRUE',
-'f' => 'FALSE',
-'F' => 'FALSE',
-0 => 'FALSE',
-00 => 'FALSE',
-'0' => 'FALSE',
-'false' => 'FALSE',
-'FALSE' => 'FALSE',
-12 => 'ERROR',
-'01' => 'ERROR',
-'00' => 'ERROR',
-' false' => 'ERROR',
-' TRUE' => 'ERROR',
-'FALSEY' => 'ERROR',
-'trueish' => 'ERROR',
-'0E0E0' => 'ERROR', ## Jungle love...
-'0 but truez' => 'ERROR',
-);
+polygon datatype invalid format
+12,34
+'12,34'
+ERROR: any
-while (my ($name,$val) = each %booltest) {
- $name = undef if $name eq 'undef';
- $t = sprintf 'Boolean quoting of %s',
- defined $name ? qq{"$name"} : 'undef';
- eval { $result = $dbh->quote($name, {pg_type => PG_BOOL}); };
+polygon datatype integers
+(12,34),(56,78)
+'(12,34),(56,78)'
+((12,34),(56,78))
+
+polygon datatype floating point and exponential numbers
+(1.2,3.4),(5e3,7E1)
+'(1.2,3.4),(5e3,7E1)'
+((1.2,3.4),(5000,70))
+
+polygon datatype many elements
+(1.2,3.4),(5,6),(7,8),(-9,10)
+'(1.2,3.4),(5,6),(7,8),(-9,10)'
+((1.2,3.4),(5,6),(7,8),(-9,10))
+
+polygon datatype fails with brackets
+[(1,2),(3,4)]
+ERROR: Invalid input for geometric type
+ERROR: any
+
+
+
+circle datatype invalid format
+(12,34)
+'(12,34)'
+ERROR: any
+
+circle datatype integers
+<(12,34),5>
+'<(12,34),5>'
+<(12,34),5>
+
+circle datatype floating point and exponential numbers
+<(-1.2,2E2),3e3>
+'<(-1.2,2E2),3e3>'
+<(-1.2,200),3000>
+
+circle datatype fails with brackets
+[(1,2),(3,4)]
+ERROR: Invalid input for circle type
+ERROR: any
+
+};
+
+$testdata =~ s/^\s+//;
+my $curtype = '';
+for my $line (split /\n\n+/ => $testdata) {
+ my ($text,$input,$quoted,$rows) = split /\n/ => $line;
+ next if ! $text;
+ $t = "Geometric type test: $text";
+ (my $type) = ($text =~ m{(\w+)});
+ last if $type eq 'LAST';
+ if ($curtype ne $type) {
+ $curtype = $type;
+ eval { $dbh->do('DEALLOCATE geotest'); }; $dbh->commit();
+ $dbh->do(qq{PREPARE geotest($type) AS INSERT INTO
dbd_pg_test_geom(x$type) VALUES (\$1)});
+ $sth = $dbh->prepare(qq{INSERT INTO dbd_pg_test_geom(x$type)
VALUES (?)});
+ $sth->bind_param(1, '', {pg_type => $typemap{$type} });
+ }
+ $dbh->do('DELETE FROM dbd_pg_test_geom');
+ eval { $qresult = $dbh->quote($input, {pg_type => $typemap{$type}}); };
+ if ($@) {
+ if ($quoted !~ /ERROR: (.+)/) {
+ fail "$t error: $@";
+ }
+ else {
+ like ($@, qr{$1}, $t);
+ }
+ }
+ else {
+ is ($qresult, $quoted, $t);
+ }
+ $dbh->commit();
+
+ eval { $dbh->do("EXECUTE geotest('$input')"); };
if ($@) {
- if ($val eq 'ERROR' and $@ =~ /Invalid boolean/) {
+ if ($rows !~ /ERROR: (.+)/) {
+ fail "$t error: $@";
+ }
+ else {
+ ## Do any error for now: i18n worries
pass $t;
}
+ }
+ $dbh->commit();
+
+ eval { $sth->execute($input); };
+ if ($@) {
+ if ($rows !~ /ERROR: (.+)/) {
+ fail $t;
+ }
else {
- fail "Failure at $t: $...@\n";
+ ## Do any error for now: i18n worries
+ pass $t;
}
- $dbh->rollback();
}
- else {
- is ($result, $val, $t);
+ $dbh->commit();
+
+ if ($rows !~ /ERROR/) {
+ $SQL = "SELECT x$type FROM dbd_pg_test_geom";
+ my $expected = [[$rows],[$rows]];
+ $result = $dbh->selectall_arrayref($SQL);
+ is_deeply($result, $expected, $t);
}
}
-## Test quoting of geometric types
-
-my @geotypes = qw/point line lseg box path polygon circle/;
-
-$dbh->do("SET search_path TO DEFAULT");
-eval { $dbh->do("DROP TABLE dbd_pg_test_geom"); }; $dbh->commit();
-
-$SQL = 'CREATE TABLE dbd_pg_test_geom (';
-for my $type (@geotypes) {
- $SQL .= "x$type $type,";
-}
-$SQL =~ s/,$/)/;
-$dbh->do($SQL);
+$t='Calling do() with non-DML placeholder works';
+$sth->finish();
$dbh->commit();
+eval {
+ $dbh->do(q{SET search_path TO ?}, undef, 'pg_catalog');
+};
+is ($@, q{}, $t);
-my %typemap = (
- point => PG_POINT,
- line => PG_LINE,
- lseg => PG_LSEG,
- box => PG_BOX,
- path => PG_PATH,
- polygon => PG_POLYGON,
- circle => PG_CIRCLE,
-);
-
-my $testdata = q{
-point datatype integers
-12,34
-'12,34'
-(12,34)
-
-point datatype floating point numbers
-1.34,667
-'1.34,667'
-(1.34,667)
-
-point datatype exponential numbers
-1e34,9E4
-'1e34,9E4'
-(1e+34,90000)
-
-point datatype plus and minus signs
-1e+34,-.45
-'1e+34,-.45'
-(1e+34,-0.45)
-
-point datatype invalid number
-123,abc
-ERROR: Invalid input for geometric type
-ERROR: any
-
-point datatype invalid format
-123
-'123'
-ERROR: any
-
-point datatype invalid format
-123,456,789
-'123,456,789'
-ERROR: any
-
-point datatype invalid format
-<(2,4),6>
-ERROR: Invalid input for geometric type
-ERROR: any
-
-point datatype invalid format
-[(1,2)]
-ERROR: Invalid input for geometric type
-ERROR: any
+$t='Calling do() with DML placeholder works';
+$dbh->commit();
+eval {
+ $dbh->do(q{SELECT ?::text}, undef, 'public');
+};
+is ($@, q{}, $t);
-line datatype integers
-12,34
-'12,34'
-ERROR: not yet implemented
+$t='Calling do() with invalid crowded placeholders fails cleanly';
+$dbh->commit();
+eval {
+ $dbh->do(q{SELECT ??}, undef, 'public', 'error');
+};
+is($dbh->state, '42601', $t);
-line datatype floating point numbers
-1.34,667
-'1.34,667'
-ERROR: not yet implemented
+$t='Prepare/execute with non-DML placeholder works';
+$dbh->commit();
+eval {
+ $sth = $dbh->prepare(q{SET search_path TO ?});
+ $sth->execute('pg_catalog');
+};
+is ($@, q{}, $t);
-line datatype exponential numbers
-1e34,9E4
-'1e34,9E4'
-ERROR: not yet implemented
+$t='Prepare/execute does not allow geometric operators';
+$dbh->commit();
+eval {
+ $sth = $dbh->prepare(q{SELECT ?- lseg '(1,0),(1,1)'});
+ $sth->execute();
+};
+like ($@, qr{unbound placeholder}, $t);
-line datatype plus and minus signs
-1e+34,-.45
-'1e+34,-.45'
-ERROR: not yet implemented
+$t='Prepare/execute allows geometric operator ?- when dollaronly is set';
+$dbh->commit();
+$dbh->{pg_placeholder_dollaronly} = 1;
+eval {
+ $sth = $dbh->prepare(q{SELECT ?- lseg '(1,0),(1,1)'});
+ $sth->execute();
+ $sth->finish();
+};
+is ($@, q{}, $t);
-line datatype invalid number
-123,abc
-ERROR: Invalid input for geometric type
-ERROR: not yet implemented
+$t='Prepare/execute allows geometric operator ?# when dollaronly set';
+$dbh->commit();
+eval {
+ $sth = $dbh->prepare(q{SELECT lseg'(1,0),(1,1)' ?# lseg '(2,3),(4,5)'});
+ $sth->execute();
+ $sth->finish();
+};
+is ($@, q{}, $t);
+$t=q{Value of placeholder_dollaronly can be retrieved};
+is ($dbh->{pg_placeholder_dollaronly}, 1, $t);
-lseg datatype invalid format
-12,34
-'12,34'
-ERROR: any
+$t=q{Prepare/execute does not allow use of raw ? and :foo forms};
+$dbh->{pg_placeholder_dollaronly} = 0;
+eval {
+ $sth = $dbh->prepare(q{SELECT uno ?: dos ? tres :foo bar $1});
+ $sth->execute();
+ $sth->finish();
+};
+like ($@, qr{mix placeholder}, $t);
-lseg datatype integers
-(12,34),(56,78)
-'(12,34),(56,78)'
-[(12,34),(56,78)]
+$t='Prepare/execute allows use of raw ? and :foo forms when dollaronly set';
+$dbh->{pg_placeholder_dollaronly} = 1;
+eval {
+ $sth = $dbh->prepare(q{SELECT uno ?: dos ? tres :foo bar $1},
{pg_placeholder_dollaronly => 1});
+ $sth->{pg_placeholder_dollaronly} = 1;
+ $sth->execute();
+ $sth->finish();
+};
+like ($@, qr{unbound placeholder}, $t);
-lseg datatype floating point and exponential numbers
-(1.2,3.4),(5e3,7E1)
-'(1.2,3.4),(5e3,7E1)'
-[(1.2,3.4),(5000,70)]
+$t='Prepare works with pg_placeholder_dollaronly';
+$dbh->{pg_placeholder_dollaronly} = 0;
+eval {
+ $sth = $dbh->prepare(q{SELECT uno ?: dos ? tres :foo bar $1},
{pg_placeholder_dollaronly => 1});
+ $sth->execute();
+ $sth->finish();
+};
+like ($@, qr{unbound placeholder}, $t);
+$t='Prepare works with identical named placeholders';
+eval {
+ $sth = $dbh->prepare(q{SELECT :row, :row, :row, :yourboat});
+ $sth->finish();
+};
+is ($@, q{}, $t);
-box datatype invalid format
-12,34
-'12,34'
-ERROR: any
+$t='Prepare works with placeholders after double slashes';
+eval {
+ $dbh->do(q{CREATE OPERATOR // ( PROCEDURE=bit, LEFTARG=int,
RIGHTARG=int )});
+ $sth = $dbh->prepare(q{SELECT ? // ?});
+ $sth->execute(1,2);
+ $sth->finish();
+};
+is ($@, q{}, $t);
-box datatype integers
-(12,34),(56,78)
-'(12,34),(56,78)'
-(56,78),(12,34)
+$t='Dollar quotes starting with a number are not treated as valid identifiers';
+eval {
+ $sth = $dbh->prepare(q{SELECT $123$ $123$});
+ $sth->execute(1);
+ $sth->finish();
+};
+like ($@, qr{Invalid placeholders}, $t);
-box datatype floating point and exponential numbers
-(1.2,3.4),(5e3,7E1)
-'(1.2,3.4),(5e3,7E1)'
-(5000,70),(1.2,3.4)
+$t='Dollar quotes with invalid characters are not parsed as identifiers';
+for my $char (qw!+ / : @ [ `!) {
+ eval {
+ $sth = $dbh->prepare(qq{SELECT \$abc${char}\$ 123
\$abc${char}\$});
+ $sth->execute();
+ $sth->finish();
+ };
+ like ($@, qr{syntax error}, $t);
+}
+$t='Dollar quotes with valid characters are parsed as identifiers';
+$dbh->rollback();
+for my $char (qw{0 9 A Z a z}) {
+ eval {
+ $sth = $dbh->prepare(qq{SELECT \$abc${char}\$ 123
\$abc${char}\$});
+ $sth->execute();
+ $sth->finish();
+ };
+ is ($@, q{}, $t);
+}
-path datatype invalid format
-12,34
-'12,34'
-ERROR: any
+SKIP: {
+ skip 'Cannot run backslash_quote tet on Postgres < 8.2', 1 if
$pgversion < 80200;
-path datatype integers
-(12,34),(56,78)
-'(12,34),(56,78)'
-((12,34),(56,78))
+ $t='Backslash quoting inside double quotes is parsed correctly';
+ $dbh->do(q{SET backslash_quote = 'on'});
+ $dbh->commit();
+ eval {
+ $sth = $dbh->prepare(q{SELECT * FROM "\" WHERE a=?});
+ $sth->execute(1);
+ $sth->finish();
+ };
+ like ($@, qr{relation ".*" does not exist}, $t);
+}
-path datatype floating point and exponential numbers
-(1.2,3.4),(5e3,7E1)
-'(1.2,3.4),(5e3,7E1)'
-((1.2,3.4),(5000,70))
+$dbh->rollback();
-path datatype alternate bracket format
-[(1.2,3.4),(5e3,7E1)]
-'[(1.2,3.4),(5e3,7E1)]'
-[(1.2,3.4),(5000,70)]
+SKIP: {
+ skip 'Cannot adjust standard_conforming_strings for testing on this
version of Postgres', 2 if $pgversion < 80200;
+ $t='Backslash quoting inside single quotes is parsed correctly with
standard_conforming_strings off';
+ eval {
+ $dbh->do(q{SET standard_conforming_strings = 'off'});
+ $sth = $dbh->prepare(q{SELECT '\', ?});
+ $sth->execute();
+ $sth->finish();
+ };
+ like ($@, qr{unterminated quoted string}, $t);
+ $dbh->rollback();
-path datatype many elements
-(1.2,3.4),(5,6),(7,8),(-9,10)
-'(1.2,3.4),(5,6),(7,8),(-9,10)'
-((1.2,3.4),(5,6),(7,8),(-9,10))
+ $t='Backslash quoting inside single quotes is parsed correctly with
standard_conforming_strings on';
+ eval {
+ $dbh->do(q{SET standard_conforming_strings = 'on'});
+ $sth = $dbh->prepare(q{SELECT '\', ?::int});
+ $sth->execute(1);
+ $sth->finish();
+ };
+ is ($@, q{}, $t);
+}
-path datatype fails with braces
-{(1,2),(3,4)}
-ERROR: Invalid input for path type
-ERROR: any
+$t='Valid integer works when quoting with SQL_INTEGER';
+my $val;
+$val = $dbh->quote('123', SQL_INTEGER);
+is ($val, 123, $t);
-polygon datatype invalid format
-12,34
-'12,34'
-ERROR: any
+$t='Invalid integer fails to pass through when quoting with SQL_INTEGER';
+$val = -1;
+eval {
+ $val = $dbh->quote('123abc', SQL_INTEGER);
+};
+like ($@, qr{Invalid integer}, $t);
+is($val, -1, $t);
-polygon datatype integers
-(12,34),(56,78)
-'(12,34),(56,78)'
-((12,34),(56,78))
+my $prefix = 'Valid float value works when quoting with SQL_FLOAT';
+for my $float ('123','0.00','0.234','23.31562',
'1.23e04','6.54e+02','4e-3','NaN','Infinity','-infinity') {
+ $t = "$prefix (value=$float)";
+ $val = -1;
+ eval { $val = $dbh->quote($float, SQL_FLOAT); };
+ is ($@, q{}, $t);
+ is ($val, $float, $t);
-polygon datatype floating point and exponential numbers
-(1.2,3.4),(5e3,7E1)
-'(1.2,3.4),(5e3,7E1)'
-((1.2,3.4),(5000,70))
+ next unless $float =~ /\w/;
-polygon datatype many elements
-(1.2,3.4),(5,6),(7,8),(-9,10)
-'(1.2,3.4),(5,6),(7,8),(-9,10)'
-((1.2,3.4),(5,6),(7,8),(-9,10))
+ my $lcfloat = lc $float;
+ $t = "$prefix (value=$lcfloat)";
+ $val = -1;
+ eval { $val = $dbh->quote($lcfloat, SQL_FLOAT); };
+ is ($@, q{}, $t);
+ is ($val, $lcfloat, $t);
-polygon datatype fails with brackets
-[(1,2),(3,4)]
-ERROR: Invalid input for geometric type
-ERROR: any
+ my $ucfloat = uc $float;
+ $t = "$prefix (value=$ucfloat)";
+ $val = -1;
+ eval { $val = $dbh->quote($ucfloat, SQL_FLOAT); };
+ is ($@, q{}, $t);
+ is ($val, $ucfloat, $t);
+}
+$prefix = 'Invalid float value fails when quoting with SQL_FLOAT';
+for my $float ('3abc','123abc','','123e+04e+34','NaNum','-infinitee') {
+ $t = "$prefix (value=$float)";
+ $val = -1;
+ eval { $val = $dbh->quote($float, SQL_FLOAT); };
+ like ($@, qr{Invalid number}, $t);
+ is ($val, -1, $t);
+}
+$dbh->rollback();
-circle datatype invalid format
-(12,34)
-'(12,34)'
-ERROR: any
+## Test placeholders plus binding
+$t='Bound placeholders enforce data types when not using server side prepares';
+$dbh->trace(0);
+$dbh->{pg_server_prepare} = 0;
+$sth = $dbh->prepare('SELECT (1+?+?)::integer');
+$sth->bind_param(1, 1, SQL_INTEGER);
+eval {
+ $sth->execute('10foo',20);
+};
+like ($@, qr{Invalid integer}, 'Invalid integer test 2');
-circle datatype integers
-<(12,34),5>
-'<(12,34),5>'
-<(12,34),5>
+## Test quoting of the "name" type
+$prefix = q{The 'name' data type does correct quoting};
-circle datatype floating point and exponential numbers
-<(-1.2,2E2),3e3>
-'<(-1.2,2E2),3e3>'
-<(-1.2,200),3000>
+for my $word (qw/User user USER trigger Trigger/) {
+ $t = qq{$prefix for the word "$word"};
+ my $got = $dbh->quote($word, { pg_type => PG_NAME });
+ $expected = qq{"$word"};
+ is($got, $expected, $t);
+}
-circle datatype fails with brackets
-[(1,2),(3,4)]
-ERROR: Invalid input for circle type
-ERROR: any
+for my $word (qw/auser userz user-user/) {
+ $t = qq{$prefix for the word "$word"};
+ my $got = $dbh->quote($word, { pg_type => PG_NAME });
+ $expected = qq{$word};
+ is($got, $expected, $t);
+}
-};
+## Test quoting of booleans
-$testdata =~ s/^\s+//;
-my $curtype = '';
-for my $line (split /\n\n+/ => $testdata) {
- my ($text,$input,$quoted,$rows) = split /\n/ => $line;
- next if ! $text;
- $t = "Geometric type test: $text";
- (my $type) = ($text =~ m{(\w+)});
- last if $type eq 'LAST';
- if ($curtype ne $type) {
- $curtype = $type;
- eval { $dbh->do('DEALLOCATE geotest'); }; $dbh->commit();
- $dbh->do(qq{PREPARE geotest($type) AS INSERT INTO
dbd_pg_test_geom(x$type) VALUES (\$1)});
- $sth = $dbh->prepare(qq{INSERT INTO dbd_pg_test_geom(x$type)
VALUES (?)});
- $sth->bind_param(1, '', {pg_type => $typemap{$type} });
- }
- $dbh->do('DELETE FROM dbd_pg_test_geom');
- eval { $qresult = $dbh->quote($input, {pg_type => $typemap{$type}}); };
- if ($@) {
- if ($quoted !~ /ERROR: (.+)/) {
- fail "$t error: $@";
- }
- else {
- like ($@, qr{$1}, $t);
- }
- }
- else {
- is ($qresult, $quoted, $t);
- }
- $dbh->commit();
+my %booltest = (
+undef => 'NULL',
+'t' => 'TRUE',
+'T' => 'TRUE',
+'true' => 'TRUE',
+'TRUE' => 'TRUE',
+1 => 'TRUE',
+01 => 'TRUE',
+'1' => 'TRUE',
+'0E0' => 'TRUE',
+'0e0' => 'TRUE',
+'0 but true' => 'TRUE',
+'0 BUT TRUE' => 'TRUE',
+'f' => 'FALSE',
+'F' => 'FALSE',
+0 => 'FALSE',
+00 => 'FALSE',
+'0' => 'FALSE',
+'false' => 'FALSE',
+'FALSE' => 'FALSE',
+12 => 'ERROR',
+'01' => 'ERROR',
+'00' => 'ERROR',
+' false' => 'ERROR',
+' TRUE' => 'ERROR',
+'FALSEY' => 'ERROR',
+'trueish' => 'ERROR',
+'0E0E0' => 'ERROR', ## Jungle love...
+'0 but truez' => 'ERROR',
+);
- eval { $dbh->do("EXECUTE geotest('$input')"); };
+while (my ($name,$val) = each %booltest) {
+ $name = undef if $name eq 'undef';
+ $t = sprintf 'Boolean quoting of %s',
+ defined $name ? qq{"$name"} : 'undef';
+ eval { $result = $dbh->quote($name, {pg_type => PG_BOOL}); };
if ($@) {
- if ($rows !~ /ERROR: (.+)/) {
- fail "$t error: $@";
- }
- else {
- ## Do any error for now: i18n worries
+ if ($val eq 'ERROR' and $@ =~ /Invalid boolean/) {
pass $t;
}
- }
- $dbh->commit();
-
- eval { $sth->execute($input); };
- if ($@) {
- if ($rows !~ /ERROR: (.+)/) {
- fail $t;
- }
else {
- ## Do any error for now: i18n worries
- pass $t;
+ fail "Failure at $t: $...@\n";
}
+ $dbh->rollback();
}
- $dbh->commit();
-
- if ($rows !~ /ERROR/) {
- $SQL = "SELECT x$type FROM dbd_pg_test_geom";
- my $expected = [[$rows],[$rows]];
- $result = $dbh->selectall_arrayref($SQL);
- is_deeply($result, $expected, $t);
+ else {
+ is ($result, $val, $t);
}
}