From 7bd422edcdf77e5813fe3983dba558a12eaf0c5e Mon Sep 17 00:00:00 2001 From: Reini Urban Date: Wed, 29 May 2013 10:03:26 -0500 Subject: [PATCH] add tests for rt_26775 and rt_76395 --- t/rt_26775-distinct.t | 137 ++++++++++++++++++++++++++++++++++++++ t/rt_76395_int_overflow.t | 52 +++++++++++++++ 2 files changed, 189 insertions(+) create mode 100644 t/rt_26775-distinct.t create mode 100644 t/rt_76395_int_overflow.t diff --git a/t/rt_26775-distinct.t b/t/rt_26775-distinct.t new file mode 100644 index 0000000..db22bdd --- /dev/null +++ b/t/rt_26775-distinct.t @@ -0,0 +1,137 @@ +#!/usr/bin/perl +use strict; +use warnings; +use DBI; +use Test::More tests => 22; + +use_ok('DBD::SQLite'); + +our $DBFILE = 'rt_26775-distinct.db'; + +my $noprintquerymsg = '(Set ENV{PRINT_QUERY} to true value to see query)'; +my $tinfo; + +# Remove stale database file. (We dont wanna keep the file). +unlink $DBFILE if -f $DBFILE; +END { unlink $DBFILE; } + +my $dbh = DBI->connect('DBI:SQLite:' . $DBFILE); +ok( ref $dbh, "create new db: $DBFILE" ); + +# ###### +# First we create our schema (attached in __DATA__) +# +my $slurp; +while (my $line = ) { + $slurp .= $line; +} +QUERY: +for my $query (split m/ ; /xms, $slurp) { + + # remove newline + leading and trailing whitespace. + chomp $query; + $query =~ s/^ \s+ //xms; + $query =~ s/ \s+ $//xms; + next QUERY if not $query; + + # execute the query. + my $sth = $dbh->prepare($query); + $tinfo = $ENV{PRINT_QUERY} ? "prepare: $query" + : "prepare: $noprintquerymsg"; + ok( ref $sth, $tinfo); + my $ret = $sth->execute( ); + $tinfo = $ENV{PRINT_QUERY} ? "execute: $query" + : "execute: $noprintquerymsg"; + ok( $ret, $tinfo); + + $sth->finish( ); +} + +# ###### +# Then we test the bug. +# + + +# We test with both 'DISTINCT(t.name) [..]' and 'DISTINCT t.name [..]' +# +my $query_with_parens = trim(q{ + SELECT DISTINCT(t.name), t.tagid + FROM objtagmap m,tags t + WHERE (m.objid = 1) + AND (t.tagid = m.tagid) +}); + +my $query_without_parens = trim(q{ + SELECT DISTINCT t.name, t.tagid + FROM objtagmap m,tags t + WHERE (m.objid = 1) + AND (t.tagid = m.tagid) +}); + +foreach my $query (($query_with_parens, $query_without_parens)) { + + # just to print readable test descriptions. + my $abbrev = substr $query, 0, 25; + + my $sth = $dbh->prepare($query); + ok( ref $sth, "prepare $abbrev" ); + my $ret = $sth->execute( ); + ok( $ret, "execute $abbrev" ); + + while (my $hres = $sth->fetchrow_hashref) { + # Here we should get two hash keys: 'name' and 'tagid'. + ok( exists $hres->{name}, 'exists $hres->{name}' ); + ok( exists $hres->{tagid}, 'exists $hres->{tagid}' ); + if (! exists $hres->{name}) { + $Data::Dumper::Varname = ''; + eval 'require Data::Dumper;'; + if (! $@) { + $Data::Dumper::Varname = 'fetchrow_hashref'; + print {*STDERR} "#[RT #26775] The keys we got was: ", + Data::Dumper::Dumper($hres), "\n"; + } + } + } + $sth->finish; +} + +$dbh->disconnect; + +sub trim { + my ($string) = @_; + $string =~ s/^ \s+ //xms; + $string =~ s/ \s+ $//xms; + $string =~ s/\s+/ /xms; + return $string; +} + +# DATA has schema for 3 tables. object, tags, and objtagmap. +# We create an article object and a tag, and then we connect the article object with the +# tag. + +__DATA__ +CREATE TABLE object ( + id INTEGER PRIMARY KEY NOT NULL, + parent INTEGER NOT NULL DEFAULT 1, + name VARCHAR(255) NOT NULL, + type CHAR(16) NOT NULL default 'directory' +); + +CREATE TABLE objtagmap ( + id INTEGER PRIMARY KEY NOT NULL, + objid INTEGER NOT NULL, + tagid INTEGER NOT NULL +); + +CREATE TABLE tags ( + tagid INTEGER PRIMARY KEY NOT NULL, + name char(32) NOT NULL +); + +INSERT INTO object (id, parent, name, type) VALUES +(1, 1, 'All about the the distinct hash key problem, and how to survive +deadly weapons', 'article'); + +INSERT INTO tags(tagid, name) VALUES (1,'bugs'); + +INSERT INTO objtagmap(id, objid, tagid) VALUES(1, 1, 1); diff --git a/t/rt_76395_int_overflow.t b/t/rt_76395_int_overflow.t new file mode 100644 index 0000000..bf3dde0 --- /dev/null +++ b/t/rt_76395_int_overflow.t @@ -0,0 +1,52 @@ +#!/usr/bin/perl + +use strict; +my $INTMAX; +BEGIN { + $| = 1; + $^W = 1; + use Config; + $INTMAX = (1 << ($Config{ivsize}*4-1)) - 1; +} +use t::lib::Test; +use Test::More tests => 7 + (2147483647 == $INTMAX ? 2 : 4); +use Test::NoWarnings; +use DBI qw(:sql_types); + +my $dbh = connect_ok(); + +# testing results +sub intmax { + my $intmax = shift; + my ($statement, $sth, $result); + $statement = "SELECT $intmax + 1"; + $sth = $dbh->prepare($statement); + ok( $sth->execute, "execute: $statement" ); + $result = $sth->fetchrow_arrayref->[0]; + is( $result, $intmax + 1, "result: $result" ); +} + +intmax($INTMAX); +intmax(2147483647) if 2147483647 != $INTMAX; + +# testing int column type, which should default to int(8) or int(4) +$dbh->do('drop table if exists artist'); +$dbh->do(<<'END_SQL'); +create table artist ( + id int not null, + name text not null +) +END_SQL + +$INTMAX = 2147483647; +my ($sth, $result); +ok( $dbh->do(qq/insert into artist (id,name) values($INTMAX+1, 'Leonardo')/), 'insert int INTMAX+1'); +$sth = $dbh->prepare('select id from artist where name=?'); +ok( $sth->execute('Leonardo'), 'bind to name' ); +$result = $sth->fetchrow_arrayref->[0]; +is( $result, $INTMAX+1, "result: $result" ); + +$sth = $dbh->prepare('select name from artist where id=?'); +ok( $sth->execute($INTMAX+1), 'bind to INTMAX+1' ); +$result = $sth->fetchrow_arrayref->[0]; +is( $result, 'Leonardo', "result: $result" );