#!/usr/bin/perl -w use strict; use warnings; use DBI; use Data::Dumper; use Test::More tests=>138 ; # qw(no_plan); my $dbh= DBI->connect('dbi:mysql:test;host=localhost;' ."mysql_read_default_file=$ENV{HOME}/.my.cnf", undef,undef, {RaiseError => 1}) or die "$DBI::errstr\n"; my ($version) = $dbh->selectrow_array(qq{select version()}); ok($version gt '5.1', 'version'); diag "version = $version"; ok_do(qq{DROP TABLE IF EXISTS t1, t2},'initializing'); my $insert_t1_values = qq{ INSERT INTO t1 VALUES (16421), (19092), (22589) }; my $insert_t2_values = qq{ INSERT INTO t2 VALUES ('2006-09-27 21:50:01',16421), ('2006-10-02 21:50:01',16421), ('2006-09-27 21:50:01',19092), ('2006-09-28 21:50:01',19092), ('2006-09-29 21:50:01',19092), ('2006-09-30 21:50:01',19092), ('2006-10-01 21:50:01',19092), ('2006-10-02 21:50:01',19092), ('2006-09-27 21:50:01',22589), ('2006-09-29 21:50:01',22589) }; my $base_t1_table = qq{CREATE TABLE t1 ( id int(8) NOT NULL #KEYS ) ENGINE=_ENGINE_ }; my $base_t2_table = qq{CREATE TABLE t2 ( taken datetime NOT NULL DEFAULT '0000-00-00 00:00:00', id int(11) NOT NULL DEFAULT '0' #KEYS ) ENGINE=_ENGINE_ }; my $t1_indexes = qq{,\n PRIMARY KEY (id)\n}; my $t2_indexes = qq{,\n PRIMARY KEY (id,taken),\nKEY taken (taken)\n}; my @partition_clauses = ( { name => 'plain', statement => q{}, }, { name => 'list by date', statement => qq{ PARTITION BY list (to_days(taken)) ( PARTITION p01 VALUES IN ( to_days('2006-09-27'), to_days('2006-09-28') ), PARTITION p02 VALUES IN ( to_days('2006-09-29'), to_days('2006-09-30') ), PARTITION p03 VALUES IN ( to_days('2006-10-01'), to_days('2006-10-02') ) ) } }, { name => 'list by number', statement => qq{ PARTITION BY list (id) ( PARTITION p01 VALUES IN ( 16421 ), PARTITION p02 VALUES IN ( 19092, 22589 ) ) } }, { name => 'range by date', statement => qq{ PARTITION BY RANGE (to_days(taken)) ( PARTITION p01 VALUES LESS THAN (732920) , PARTITION p02 VALUES LESS THAN (732950) , PARTITION p03 VALUES LESS THAN MAXVALUE ) ; } }, { name => 'range by number', statement => qq{ PARTITION BY RANGE (id) ( PARTITION p01 VALUES LESS THAN (17000) , PARTITION p02 VALUES LESS THAN (19000) , PARTITION p03 VALUES LESS THAN (22000) , PARTITION p4 VALUES LESS THAN MAXVALUE ) ; } }, { name => 'key by date', statement => qq{ PARTITION BY KEY () PARTITIONS 4 } }, { name => 'key by number', statement => qq{ PARTITION BY KEY (id) PARTITIONS 4 } }, { name => 'hash by date', statement => qq{ PARTITION BY HASH (to_days(taken)) PARTITIONS 4 } }, { name => 'hash by number', statement => qq{ PARTITION BY HASH (id) PARTITIONS 4 } }, ); my @engines = ( {name => 'MyISAM', has_keys => 1}, {name => 'InnoDB', has_keys => 1}, {name => 'Archive', has_keys => 0}, ); my $test_query = qq{ SELECT t1.id AS _WHAT_ FROM t1 WHERE t1.id IN ( SELECT distinct id FROM t2 WHERE taken BETWEEN \@f_date AND date_add(\@t_date, INTERVAL 1 DAY)) ORDER BY t1.id }; ok_do(qq{set \@f_date='2006-09-28'},'setting f_date'); ok_do(qq{set \@t_date='2006-10-02'},'setting t_date'); my $base_recs; for my $engine ( @engines ) { my $t1_query = $base_t1_table; if ($engine->{has_keys}) { $t1_query =~ s/#KEYS/$t1_indexes/; } $t1_query =~ s/_ENGINE_/$engine->{name}/; ok_do($t1_query, 'creating t1 '. $engine->{name}); ok_do($insert_t1_values, 'inserting t1 values'); for my $part (@partition_clauses) { my $t2_query = $base_t2_table; if ($engine->{has_keys}) { $t2_query =~ s/#KEYS/$t2_indexes/; } else { next if $part->{statement} =~ /\bkey\b/i; } $t2_query =~ s/_ENGINE_/$engine->{name}/; $t2_query .= $part->{statement} ; ok_do( $t2_query, 'creating t1 ' . $engine->{name} . ' ' . $part->{name}); ok_do( $insert_t2_values, 'inserting t2 values '. $engine->{name} . ' ' . $part->{name}); my $exec_query = $test_query; $exec_query =~ s/_WHAT_/$dbh->quote('result ' . $engine->{name} . ' ' . $part->{name})/e; my $recs = $dbh->selectall_arrayref($exec_query); ok($recs , 'running '. $engine->{name} . ' ' . $part->{name} ); if ($part->{name} eq 'plain') { $base_recs = $recs; } unless ( is_deeply($recs, $base_recs, 'data found ' . $engine->{name} . ' ' . $part->{name} )) { diag out($recs,$base_recs); } ok_do(qq{drop table if exists t2}, 'cleaning up t2 '. $engine->{name} . ' ' . $part->{name} ); } ok_do(qq{drop table if exists t1}, 'cleaning up t1 '. $engine->{name} ); } sub ok_do { my ($query, $msg, @params) = @_; my $result; if (@params) { eval {$result = $dbh->do($query, undef, @params)}; } else { eval {$result = $dbh->do($query)}; } if ($@) { print $query,$/; die $@; } return ok($result, $msg); } sub out { my ($got, $expected) = @_; return "got : [" . join( q{,}, map {join( q{:},@$_ ) } @$got) . q{] - } . "expected: [" . join( q{,}, map {join( q{:},@$_ ) } @$expected) . q{]}; }