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
|
use strict;
use warnings;
use lib "t/lib";
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
use Test::More;
use if -d ".git", "Test::FailWarnings";
use DBD::SQLite;
use DBD::SQLite::Constants;
my @function_flags = (undef, 0);
if ($DBD::SQLite::sqlite_version_number >= 3008003) {
push @function_flags, DBD::SQLite::Constants::SQLITE_DETERMINISTIC;
}
# Create the aggregate test packages
SCOPE: {
package count_aggr;
sub new {
bless { count => 0 }, shift;
}
sub step {
$_[0]{count}++;
return;
}
sub finalize {
my $c = $_[0]{count};
$_[0]{count} = undef;
return $c;
}
package obj_aggregate;
sub new {
bless { count => 0 }, shift;
}
sub step {
$_[0]{count}++ if defined $_[1];
}
sub finalize {
my $c = $_[0]{count};
$_[0]{count} = undef;
return $c;
}
package fail_aggregate;
sub new {
my $class = shift;
if ( ref $class ) {
die "new() failed on request" if $class->{'fail'} eq 'new';
return undef if $class->{'fail'} eq 'undef';
return bless { %$class }, ref $class;
} else {
return bless { 'fail' => $_[0] }, $class;
}
}
sub step {
die "step() failed on request" if $_[0]{fail} eq 'step';
}
sub finalize {
die "finalize() failed on request" if $_[0]{fail} eq 'finalize';
}
}
foreach my $call_func (@CALL_FUNCS) { for my $flags (@function_flags) {
my $dbh = connect_ok( PrintError => 0 );
$dbh->do( "CREATE TABLE aggr_test ( field )" );
foreach my $val ( qw/NULL 1 'test'/ ) {
$dbh->do( "INSERT INTO aggr_test VALUES ( $val )" );
}
ok($dbh->$call_func( "newcount", 0, "count_aggr", defined $flags ? $flags : (), "create_aggregate" ));
my $result = $dbh->selectrow_arrayref( "SELECT newcount() FROM aggr_test" );
ok( $result && $result->[0] == 3 );
# Make sure that the init() function is called correctly
$result = $dbh->selectall_arrayref( "SELECT newcount() FROM aggr_test GROUP BY field" );
ok( @$result == 3 && $result->[0][0] == 1 && $result->[1][0] == 1 );
# Test aggregate on empty table
$dbh->do( "DROP TABLE aggr_empty_test;" );
$dbh->do( "CREATE TABLE aggr_empty_test ( field )" );
$result = $dbh->selectrow_arrayref( "SELECT newcount() FROM aggr_empty_test" );
ok( $result && !$result->[0] );
# Make sure that the init() function is called correctly
$result = $dbh->selectrow_arrayref( "SELECT newcount() FROM aggr_empty_test" );
ok( $result && !$result->[0] );
ok($dbh->$call_func( "defined", 1, 'obj_aggregate', defined $flags ? $flags : (), "create_aggregate" ));
$result = $dbh->selectrow_arrayref( "SELECT defined(field) FROM aggr_test" );
ok( $result && $result->[0] == 2 );
$result = $dbh->selectrow_arrayref( "SELECT defined(field) FROM aggr_test" );
ok( $result && $result->[0] == 2 );
$result = $dbh->selectrow_arrayref( "SELECT defined(field) FROM aggr_empty_test" );
ok( $result && !$result->[0] );
$result = $dbh->selectrow_arrayref( "SELECT defined(field) FROM aggr_empty_test" );
ok( $result && !$result->[0] );
my $last_warn;
local $SIG{__WARN__} = sub { $last_warn = join "", @_ };
foreach my $fail ( qw/ new step finalize/ ) {
$last_warn = '';
my $aggr = fail_aggregate->new( $fail );
ok($dbh->$call_func( "fail_$fail", -1, $aggr, defined $flags ? $flags : (), 'create_aggregate' ));
$result = $dbh->selectrow_arrayref( "SELECT fail_$fail() FROM aggr_test" );
# ok( !$result && $DBI::errstr =~ /$fail\(\) failed on request/ );
ok( !defined $result->[0] && $last_warn =~ /$fail\(\) failed on request/ );
# No need to check this one, since step() will never be called
# on an empty table
next if $fail eq 'step';
$result = $dbh->selectrow_arrayref( "SELECT fail_$fail() FROM aggr_empty_test" );
# ok( !$result && $DBI::errstr =~ /$fail\(\) failed on request/ );
ok( !defined $result->[0] && $last_warn =~ /$fail\(\) failed on request/ );
}
my $aggr = fail_aggregate->new( 'undef' );
$last_warn = '';
ok($dbh->$call_func( "fail_undef", -1, $aggr, defined $flags ? $flags : (), 'create_aggregate' ));
$result = $dbh->selectrow_arrayref( "SELECT fail_undef() FROM aggr_test" );
# ok( !$result && $DBI::errstr =~ /new\(\) should return a blessed reference/ );
ok( !defined $result->[0] && $last_warn =~ /new\(\) should return a blessed reference/ );
$dbh->disconnect;
}}
done_testing;
|