mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-01 18:25:59 +00:00

* PT-2156 - Fix tests for lib
- Fixed tests broken for lib/TableParser.pm after fix for PT-1059
- Updated tests for lib/TableParser.pm that are broken due to SHOW CREATE TABLE output format change in 8.0
- Updated modules for all tools that use lib/TableParser.pm
* Revert "Fixed pt-archiver tests"
This reverts commit a3ab87b12e
.
This commit wa needed, because removed code in sandbox/slave_channels.sql broked the test. Proper fix would be to do not remove channel names rather than chaging the test. So revertig it.
* PT-2156 - Fix tests for lib
- Updated test t/lib/TableChecksum.t so it reflects changes, introduced in the fix for PT-2016
- Updated test t/lib/RowChecksum.t so it reflects changes added to in the fix for PT-2138: UTF8 support
- Uncommented SQL in sandbox/slave_channels.sql that made t/lib/MasterSlave.t to fail
- Added check for undef into t/pt-archiver/archive_using_channels.t
- Updated lib/Cxn.pm so it uses $dbh->{Active} after issue with the ping() call, reported at https://github.com/perl5-dbi/DBD-mysql/issues/306
* PT-2156 - Fix tests for lib
- Impoved the fix for PT-2016, so it does not files with keys with USING keyword
- Added brackets to expression in lib/TableNibbler.pm, so it does not crap query wit many indexes with OR keyword
- Adjusted test t/lib/TableNibbler.t, so it reflects above chages
- Modified lib/Cxn.pm, so it has workaround for https://github.com/perl5-dbi/DBD-mysql/issues/306 , introduced in DBD::mysql 4.0.50
- Updated tests: added debugging code and cleanups
- Updated modules for tools
736 lines
29 KiB
Perl
736 lines
29 KiB
Perl
#!/usr/bin/perl
|
|
|
|
BEGIN {
|
|
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
|
|
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
|
|
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
|
|
};
|
|
|
|
use strict;
|
|
use warnings FATAL => 'all';
|
|
use English qw(-no_match_vars);
|
|
use Test::More tests => 26;
|
|
|
|
use TableParser;
|
|
use TableNibbler;
|
|
use Quoter;
|
|
use PerconaTest;
|
|
|
|
my $q = new Quoter();
|
|
my $tp = new TableParser(Quoter => $q);
|
|
my $n = new TableNibbler(
|
|
TableParser => $tp,
|
|
Quoter => $q,
|
|
);
|
|
|
|
my $t;
|
|
|
|
$t = $tp->parse( load_file('t/lib/samples/sakila.film.sql') );
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt (
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'PRIMARY',
|
|
),
|
|
{
|
|
cols => [qw(film_id title description release_year language_id
|
|
original_language_id rental_duration rental_rate
|
|
length replacement_cost rating special_features
|
|
last_update)],
|
|
index => 'PRIMARY',
|
|
where => '((`film_id` >= ?))',
|
|
slice => [0],
|
|
scols => [qw(film_id)],
|
|
boundaries => {
|
|
'>=' => '((`film_id` >= ?))',
|
|
'>' => '((`film_id` > ?))',
|
|
'<=' => '((`film_id` <= ?))',
|
|
'<' => '((`film_id` < ?))',
|
|
},
|
|
},
|
|
'asc stmt on sakila.film',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_del_stmt (
|
|
tbl_struct => $t,
|
|
),
|
|
{
|
|
cols => [qw(film_id)],
|
|
index => 'PRIMARY',
|
|
where => '(`film_id` = ?)',
|
|
slice => [0],
|
|
scols => [qw(film_id)],
|
|
},
|
|
'del stmt on sakila.film',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt (
|
|
tbl_struct => $t,
|
|
index => 'PRIMARY',
|
|
),
|
|
{
|
|
cols => [qw(film_id title description release_year language_id
|
|
original_language_id rental_duration rental_rate
|
|
length replacement_cost rating special_features
|
|
last_update)],
|
|
index => 'PRIMARY',
|
|
where => '((`film_id` >= ?))',
|
|
slice => [0],
|
|
scols => [qw(film_id)],
|
|
boundaries => {
|
|
'>=' => '((`film_id` >= ?))',
|
|
'>' => '((`film_id` > ?))',
|
|
'<=' => '((`film_id` <= ?))',
|
|
'<' => '((`film_id` < ?))',
|
|
},
|
|
},
|
|
'defaults to all columns',
|
|
);
|
|
|
|
throws_ok(
|
|
sub {
|
|
$n->generate_asc_stmt (
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'title',
|
|
)
|
|
},
|
|
qr/Index 'title' does not exist in table/,
|
|
'Error on nonexistent index',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt (
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'idx_title',
|
|
),
|
|
{
|
|
cols => [qw(film_id title description release_year language_id
|
|
original_language_id rental_duration rental_rate
|
|
length replacement_cost rating special_features
|
|
last_update)],
|
|
index => 'idx_title',
|
|
where => '((`title` >= ?))',
|
|
slice => [1],
|
|
scols => [qw(title)],
|
|
boundaries => {
|
|
'>=' => '((`title` >= ?))',
|
|
'>' => '((`title` > ?))',
|
|
'<=' => '((`title` <= ?))',
|
|
'<' => '((`title` < ?))',
|
|
},
|
|
},
|
|
'asc stmt on sakila.film with different index',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_del_stmt (
|
|
tbl_struct => $t,
|
|
index => 'idx_title',
|
|
cols => [qw(film_id)],
|
|
),
|
|
{
|
|
cols => [qw(film_id title description release_year language_id original_language_id rental_duration rental_rate length replacement_cost rating special_features last_update)],
|
|
index => 'idx_title',
|
|
where => '(`film_id` = ? AND `title` = ? AND ((? IS NULL AND `description` IS NULL) OR (`description` = ?)) AND ((? IS NULL AND `release_year` IS NULL) OR (`release_year` = ?)) AND `language_id` = ? AND ((? IS NULL AND `original_language_id` IS NULL) OR (`original_language_id` = ?)) AND `rental_duration` = ? AND `rental_rate` = ? AND ((? IS NULL AND `length` IS NULL) OR (`length` = ?)) AND `replacement_cost` = ? AND ((? IS NULL AND `rating` IS NULL) OR (`rating` = ?)) AND ((? IS NULL AND `special_features` IS NULL) OR (`special_features` = ?)) AND `last_update` = ?)',
|
|
slice => [ 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 10, 11, 11, 12 ],
|
|
scols => [qw( film_id title description description release_year release_year language_id original_language_id original_language_id
|
|
rental_duration rental_rate length length replacement_cost rating rating special_features special_features last_update)],
|
|
|
|
},
|
|
'del stmt on sakila.film with different index and extra column',
|
|
);
|
|
|
|
# TableParser::find_best_index() is case-insensitive, returning the
|
|
# correct case even if the wrong case is given. But generate_asc_stmt()
|
|
# no longer calls find_best_index() so this test is a moot point.
|
|
is_deeply(
|
|
$n->generate_asc_stmt (
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'idx_title',
|
|
),
|
|
{
|
|
cols => [qw(film_id title description release_year language_id
|
|
original_language_id rental_duration rental_rate
|
|
length replacement_cost rating special_features
|
|
last_update)],
|
|
index => 'idx_title',
|
|
where => '((`title` >= ?))',
|
|
slice => [1],
|
|
scols => [qw(title)],
|
|
boundaries => {
|
|
'>=' => '((`title` >= ?))',
|
|
'>' => '((`title` > ?))',
|
|
'<=' => '((`title` <= ?))',
|
|
'<' => '((`title` < ?))',
|
|
},
|
|
},
|
|
'Index returned in correct lettercase',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt (
|
|
tbl_struct => $t,
|
|
cols => [qw(title)],
|
|
index => 'PRIMARY',
|
|
),
|
|
{
|
|
cols => [qw(title film_id)],
|
|
index => 'PRIMARY',
|
|
where => '((`film_id` >= ?))',
|
|
slice => [1],
|
|
scols => [qw(film_id)],
|
|
boundaries => {
|
|
'>=' => '((`film_id` >= ?))',
|
|
'>' => '((`film_id` > ?))',
|
|
'<=' => '((`film_id` <= ?))',
|
|
'<' => '((`film_id` < ?))',
|
|
},
|
|
},
|
|
'Required columns added to SELECT list',
|
|
);
|
|
|
|
# ##########################################################################
|
|
# Switch to the rental table
|
|
# ##########################################################################
|
|
$t = $tp->parse( load_file('t/lib/samples/sakila.rental.sql') );
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt(
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'rental_date',
|
|
),
|
|
{
|
|
cols => [qw(rental_id rental_date inventory_id customer_id
|
|
return_date staff_id last_update)],
|
|
index => 'rental_date',
|
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?)'
|
|
. ' OR (`rental_date` = ? AND `inventory_id` = ? AND `customer_id` >= ?))',
|
|
slice => [1, 1, 2, 1, 2, 3],
|
|
scols => [qw(rental_date rental_date inventory_id rental_date inventory_id customer_id)],
|
|
boundaries => {
|
|
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` >= ?))',
|
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` > ?))',
|
|
'<=' => '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` <= ?))',
|
|
'<' => '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` < ?))',
|
|
},
|
|
},
|
|
'Alternate index on sakila.rental',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_del_stmt (
|
|
tbl_struct => $t,
|
|
index => 'rental_date',
|
|
),
|
|
{
|
|
cols => [qw(rental_date inventory_id customer_id)],
|
|
index => 'rental_date',
|
|
where => '(`rental_date` = ? AND `inventory_id` = ? AND `customer_id` = ?)',
|
|
slice => [0, 1, 2],
|
|
scols => [qw(rental_date inventory_id customer_id)],
|
|
},
|
|
'Alternate index on sakila.rental delete statement',
|
|
);
|
|
|
|
# Check that I can select from one table and insert into another OK
|
|
my $f = $tp->parse( load_file('t/lib/samples/sakila.film.sql') );
|
|
is_deeply(
|
|
$n->generate_ins_stmt(
|
|
ins_tbl => $f,
|
|
sel_cols => $t->{cols},
|
|
),
|
|
{
|
|
cols => [qw(last_update)],
|
|
slice => [6],
|
|
},
|
|
'Generated an INSERT statement from film into rental',
|
|
);
|
|
|
|
my $sel_tbl = $tp->parse( load_file('t/lib/samples/issue_131_sel.sql') );
|
|
my $ins_tbl = $tp->parse( load_file('t/lib/samples/issue_131_ins.sql') );
|
|
is_deeply(
|
|
$n->generate_ins_stmt(
|
|
ins_tbl => $ins_tbl,
|
|
sel_cols => $sel_tbl->{cols},
|
|
),
|
|
{
|
|
cols => [qw(id name)],
|
|
slice => [0, 2],
|
|
},
|
|
'INSERT stmt with different col order and a missing ins col'
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt(
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'rental_date',
|
|
asc_first => 1,
|
|
),
|
|
{
|
|
cols => [qw(rental_id rental_date inventory_id customer_id
|
|
return_date staff_id last_update)],
|
|
index => 'rental_date',
|
|
where => '((`rental_date` >= ?))',
|
|
slice => [1],
|
|
scols => [qw(rental_date)],
|
|
boundaries => {
|
|
'>=' => '((`rental_date` >= ?))',
|
|
'>' => '((`rental_date` > ?))',
|
|
'<=' => '((`rental_date` <= ?))',
|
|
'<' => '((`rental_date` < ?))',
|
|
},
|
|
},
|
|
'Alternate index with asc_first on sakila.rental',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt(
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'rental_date',
|
|
n_index_cols => 2,
|
|
),
|
|
{
|
|
cols => [qw(rental_id rental_date inventory_id customer_id
|
|
return_date staff_id last_update)],
|
|
index => 'rental_date',
|
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` >= ?))',
|
|
slice => [qw(1 1 2)],
|
|
scols => [qw(rental_date rental_date inventory_id)],
|
|
boundaries => {
|
|
'<' =>
|
|
'((`rental_date` < ?) OR (`rental_date` = ? AND `inventory_id` < ?))',
|
|
'<=' =>
|
|
'((`rental_date` < ?) OR (`rental_date` = ? AND `inventory_id` <= ?))',
|
|
'>' =>
|
|
'((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?))',
|
|
'>=' =>
|
|
'((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` >= ?))'
|
|
},
|
|
},
|
|
'Use only N left-most columns of the index',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt(
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'rental_date',
|
|
n_index_cols => 5,
|
|
),
|
|
{
|
|
cols => [qw(rental_id rental_date inventory_id customer_id
|
|
return_date staff_id last_update)],
|
|
index => 'rental_date',
|
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?)'
|
|
. ' OR (`rental_date` = ? AND `inventory_id` = ? AND `customer_id` >= ?))',
|
|
slice => [1, 1, 2, 1, 2, 3],
|
|
scols => [qw(rental_date rental_date inventory_id rental_date inventory_id customer_id)],
|
|
boundaries => {
|
|
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` >= ?))',
|
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` > ?))',
|
|
'<=' => '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` <= ?))',
|
|
'<' => '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` < ?))',
|
|
},
|
|
},
|
|
"Don't crash if N > number of index columns"
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt(
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'rental_date',
|
|
asc_only => 1,
|
|
),
|
|
{
|
|
cols => [qw(rental_id rental_date inventory_id customer_id
|
|
return_date staff_id last_update)],
|
|
index => 'rental_date',
|
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?)'
|
|
. ' OR (`rental_date` = ? AND `inventory_id` = ? AND `customer_id` > ?))',
|
|
slice => [1, 1, 2, 1, 2, 3],
|
|
scols => [qw(rental_date rental_date inventory_id rental_date inventory_id customer_id)],
|
|
boundaries => {
|
|
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` >= ?))',
|
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` > ?))',
|
|
'<=' => '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` <= ?))',
|
|
'<' => '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` < ?))',
|
|
},
|
|
},
|
|
'Alternate index on sakila.rental with strict ascending',
|
|
);
|
|
|
|
# ##########################################################################
|
|
# Switch to the rental table with customer_id nullable
|
|
# ##########################################################################
|
|
$t = $tp->parse( load_file('t/lib/samples/sakila.rental.null.sql') );
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt(
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'rental_date',
|
|
),
|
|
{
|
|
cols => [qw(rental_id rental_date inventory_id customer_id
|
|
return_date staff_id last_update)],
|
|
index => 'rental_date',
|
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?)'
|
|
. ' OR (`rental_date` = ? AND `inventory_id` = ? AND '
|
|
. '(? IS NULL OR `customer_id` >= ?)))',
|
|
slice => [1, 1, 2, 1, 2, 3, 3],
|
|
scols => [qw(rental_date rental_date inventory_id rental_date inventory_id customer_id customer_id)],
|
|
boundaries => {
|
|
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND (? IS NULL OR `customer_id` >= ?)))',
|
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) OR '
|
|
. '(`rental_date` = ? AND `inventory_id` = ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
|
. 'OR (`customer_id` > ?))))',
|
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
#. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
# . '= ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
|
# . 'OR (`customer_id` > ?))))',
|
|
'<=' => '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND (? IS NULL OR `customer_id` <= ?)))',
|
|
'<' => '((`rental_date` < ?) OR (`rental_date` = ? AND `inventory_id` < ?) OR '
|
|
. '((? IS NOT NULL AND `customer_id` IS NULL) OR (`customer_id` < ?)) OR '
|
|
. '(`rental_date` = ? AND `inventory_id` = ?))',
|
|
|
|
# '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
#. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
#. '= ? AND ((? IS NOT NULL AND `customer_id` IS NULL) '
|
|
#. 'OR (`customer_id` < ?))))',
|
|
},
|
|
},
|
|
'Alternate index on sakila.rental with nullable customer_id',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_del_stmt (
|
|
tbl_struct => $t,
|
|
index => 'rental_date',
|
|
),
|
|
{
|
|
cols => [qw(rental_date inventory_id customer_id)],
|
|
index => 'rental_date',
|
|
where => '(`rental_date` = ? AND `inventory_id` = ? AND '
|
|
. '((? IS NULL AND `customer_id` IS NULL) OR (`customer_id` = ?)))',
|
|
slice => [0, 1, 2, 2],
|
|
scols => [qw(rental_date inventory_id customer_id customer_id)],
|
|
},
|
|
'Alternate index on sakila.rental delete statement with nullable customer_id',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt(
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'rental_date',
|
|
asc_only => 1,
|
|
),
|
|
{
|
|
cols => [qw(rental_id rental_date inventory_id customer_id
|
|
return_date staff_id last_update)],
|
|
index => 'rental_date',
|
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) OR '
|
|
. '(`rental_date` = ? AND `inventory_id` = ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
|
. 'OR (`customer_id` > ?))))',
|
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?)'
|
|
#. ' OR (`rental_date` = ? AND `inventory_id` = ? AND '
|
|
#. '((? IS NULL AND `customer_id` IS NOT NULL) OR (`customer_id` > ?))))',
|
|
slice => [1, 1, 2, 1, 2, 3, 3],
|
|
scols => [qw(rental_date rental_date inventory_id rental_date inventory_id customer_id customer_id)],
|
|
boundaries => {
|
|
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND (? IS NULL OR `customer_id` >= ?)))',
|
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?) OR '
|
|
. '(`rental_date` = ? AND `inventory_id` = ? AND ((? IS NULL AND `customer_id` IS NOT NULL) OR '
|
|
. '(`customer_id` > ?))))',
|
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
#. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
#. '= ? AND ((? IS NULL AND `customer_id` IS NOT NULL) '
|
|
#. 'OR (`customer_id` > ?))))',
|
|
'<=' => '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND (? IS NULL OR `customer_id` <= ?)))',
|
|
'<' => '((`rental_date` < ?) OR (`rental_date` = ? AND `inventory_id` < ?) OR '
|
|
. '((? IS NOT NULL AND `customer_id` IS NULL) OR (`customer_id` < ?)) OR '
|
|
. '(`rental_date` = ? AND `inventory_id` = ?))',
|
|
# '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
#. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
#. '= ? AND ((? IS NOT NULL AND `customer_id` IS NULL) '
|
|
#. 'OR (`customer_id` < ?))))',
|
|
},
|
|
},
|
|
'Alternate index on sakila.rental with nullable customer_id and strict ascending',
|
|
);
|
|
|
|
# ##########################################################################
|
|
# Switch to the rental table with inventory_id nullable
|
|
# ##########################################################################
|
|
$t = $tp->parse( load_file('t/lib/samples/sakila.rental.null2.sql') );
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt(
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'rental_date',
|
|
),
|
|
{
|
|
cols => [qw(rental_id rental_date inventory_id customer_id
|
|
return_date staff_id last_update)],
|
|
index => 'rental_date',
|
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL)'
|
|
. ' OR (`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
|
. '(`inventory_id` = ?)) AND `customer_id` >= ?))',
|
|
# '((`rental_date` > ?) OR '
|
|
#. '(`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?)))'
|
|
#. ' OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) '
|
|
#. 'OR (`inventory_id` = ?)) AND `customer_id` >= ?))',
|
|
slice => [1, 1, 2, 2, 1, 2, 2, 3],
|
|
scols => [qw(rental_date rental_date inventory_id inventory_id
|
|
rental_date inventory_id inventory_id customer_id)],
|
|
boundaries => {
|
|
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
|
. '(`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
|
. '(`inventory_id` = ?)) AND `customer_id` >= ?))',
|
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
#. '((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` '
|
|
#. '> ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` '
|
|
#. 'IS NULL) OR (`inventory_id` = ?)) AND `customer_id` >= ?))',
|
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
|
. '(`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
|
. '(`inventory_id` = ?)) AND `customer_id` > ?))',
|
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL '
|
|
#. 'AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?))) OR '
|
|
#. '(`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) '
|
|
#. 'OR (`inventory_id` = ?)) AND `customer_id` > ?))',
|
|
'<=' => '((`rental_date` < ?) OR ((? IS NOT NULL AND `inventory_id` IS NULL) OR (`inventory_id` < ?)) '
|
|
. 'OR (`rental_date` = ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
|
. '(`inventory_id` = ?)) AND `customer_id` <= ?))',
|
|
# '((`rental_date` < ?) OR (`rental_date` = ? AND ((? IS NOT '
|
|
#. 'NULL AND `inventory_id` IS NULL) OR (`inventory_id` < ?))) OR '
|
|
#. '(`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) '
|
|
#. 'OR (`inventory_id` = ?)) AND `customer_id` <= ?))',
|
|
'<' => '((`rental_date` < ?) OR ((? IS NOT NULL AND `inventory_id` IS NULL) OR (`inventory_id` < ?)) '
|
|
. 'OR (`rental_date` = ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
|
. '(`inventory_id` = ?)) AND `customer_id` < ?))',
|
|
# '((`rental_date` < ?) OR (`rental_date` = ? AND ((? IS NOT '
|
|
#. 'NULL AND `inventory_id` IS NULL) OR (`inventory_id` < ?))) '
|
|
#. 'OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS '
|
|
#. 'NULL) OR (`inventory_id` = ?)) AND `customer_id` < ?))',
|
|
},
|
|
},
|
|
'Alternate index on sakila.rental with nullable inventory_id',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt(
|
|
tbl_struct => $t,
|
|
cols => $t->{cols},
|
|
index => 'rental_date',
|
|
asc_only => 1,
|
|
),
|
|
{
|
|
cols => [qw(rental_id rental_date inventory_id customer_id
|
|
return_date staff_id last_update)],
|
|
index => 'rental_date',
|
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
|
. '(`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
|
. '(`inventory_id` = ?)) AND `customer_id` > ?))',
|
|
# '((`rental_date` > ?) OR '
|
|
#. '(`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?)))'
|
|
#. ' OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) '
|
|
#. 'OR (`inventory_id` = ?)) AND `customer_id` > ?))',
|
|
slice => [1, 1, 2, 2, 1, 2, 2, 3],
|
|
scols => [qw(rental_date rental_date inventory_id inventory_id
|
|
rental_date inventory_id inventory_id customer_id)],
|
|
boundaries => {
|
|
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
|
. '(`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
|
. '(`inventory_id` = ?)) AND `customer_id` >= ?))',
|
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
#. '((? IS NULL AND `inventory_id` IS NOT NULL) OR (`inventory_id` '
|
|
#. '> ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` '
|
|
#. 'IS NULL) OR (`inventory_id` = ?)) AND `customer_id` >= ?))',
|
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NOT NULL) OR '
|
|
. '(`inventory_id` > ?))) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
|
. '(`inventory_id` = ?)) AND `customer_id` > ?))',
|
|
# '((`rental_date` > ?) OR (`rental_date` = ? AND ((? IS NULL '
|
|
#. 'AND `inventory_id` IS NOT NULL) OR (`inventory_id` > ?))) OR '
|
|
#. '(`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) '
|
|
#. 'OR (`inventory_id` = ?)) AND `customer_id` > ?))',
|
|
'<=' => '((`rental_date` < ?) OR ((? IS NOT NULL AND `inventory_id` IS NULL) OR (`inventory_id` < ?)) OR '
|
|
. '(`rental_date` = ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
|
. '(`inventory_id` = ?)) AND `customer_id` <= ?))',
|
|
# '((`rental_date` < ?) OR (`rental_date` = ? AND ((? IS NOT '
|
|
#. 'NULL AND `inventory_id` IS NULL) OR (`inventory_id` < ?))) OR '
|
|
#. '(`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) '
|
|
#. 'OR (`inventory_id` = ?)) AND `customer_id` <= ?))',
|
|
'<' => '((`rental_date` < ?) OR ((? IS NOT NULL AND `inventory_id` IS NULL) OR (`inventory_id` < ?)) OR '
|
|
. '(`rental_date` = ?) OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS NULL) OR '
|
|
. '(`inventory_id` = ?)) AND `customer_id` < ?))',
|
|
#'((`rental_date` < ?) OR (`rental_date` = ? AND ((? IS NOT '
|
|
#. 'NULL AND `inventory_id` IS NULL) OR (`inventory_id` < ?))) '
|
|
#. 'OR (`rental_date` = ? AND ((? IS NULL AND `inventory_id` IS '
|
|
#. 'NULL) OR (`inventory_id` = ?)) AND `customer_id` < ?))',
|
|
},
|
|
},
|
|
'Alternate index on sakila.rental with nullable inventory_id and strict ascending',
|
|
);
|
|
|
|
# ##########################################################################
|
|
# Switch to the rental table with cols in a different order.
|
|
# ##########################################################################
|
|
$t = $tp->parse( load_file('t/lib/samples/sakila.rental.remix.sql') );
|
|
|
|
is_deeply(
|
|
$n->generate_asc_stmt(
|
|
tbl_struct => $t,
|
|
index => 'rental_date',
|
|
),
|
|
{
|
|
cols => [qw(rental_id rental_date customer_id inventory_id
|
|
return_date staff_id last_update)],
|
|
index => 'rental_date',
|
|
where => '((`rental_date` > ?) OR (`rental_date` = ? AND `inventory_id` > ?)'
|
|
. ' OR (`rental_date` = ? AND `inventory_id` = ? AND `customer_id` >= ?))',
|
|
slice => [1, 1, 3, 1, 3, 2],
|
|
scols => [qw(rental_date rental_date inventory_id rental_date inventory_id customer_id)],
|
|
boundaries => {
|
|
'>=' => '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` >= ?))',
|
|
'>' => '((`rental_date` > ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` > ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` > ?))',
|
|
'<=' => '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` <= ?))',
|
|
'<' => '((`rental_date` < ?) OR (`rental_date` = ? AND '
|
|
. '`inventory_id` < ?) OR (`rental_date` = ? AND `inventory_id` '
|
|
. '= ? AND `customer_id` < ?))',
|
|
},
|
|
},
|
|
'Out-of-order index on sakila.rental',
|
|
);
|
|
|
|
# ##########################################################################
|
|
# Switch to table without any indexes
|
|
# ##########################################################################
|
|
$t = $tp->parse( load_file('t/lib/samples/t1.sql') );
|
|
|
|
# This test is no longer needed because TableSyncNibble shouldn't
|
|
# ask TableNibbler to asc an indexless table.
|
|
# throws_ok(
|
|
# sub {
|
|
# $n->generate_asc_stmt (
|
|
# tbl_struct => $t,
|
|
# )
|
|
# },
|
|
# qr/Cannot find an ascendable index in table/,
|
|
# 'Error when no good index',
|
|
# );
|
|
|
|
is_deeply(
|
|
$n->generate_cmp_where(
|
|
cols => [qw(a b c d)],
|
|
slice => [0, 3],
|
|
is_nullable => {},
|
|
type => '>=',
|
|
),
|
|
{
|
|
scols => [qw(a a d)],
|
|
slice => [0, 0, 3],
|
|
where => '((`a` > ?) OR (`a` = ? AND `d` >= ?))',
|
|
},
|
|
'WHERE for >=',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_cmp_where(
|
|
cols => [qw(a b c d)],
|
|
slice => [0, 3],
|
|
is_nullable => {},
|
|
type => '>',
|
|
),
|
|
{
|
|
scols => [qw(a a d)],
|
|
slice => [0, 0, 3],
|
|
where => '((`a` > ?) OR (`a` = ? AND `d` > ?))',
|
|
},
|
|
'WHERE for >',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_cmp_where(
|
|
cols => [qw(a b c d)],
|
|
slice => [0, 3],
|
|
is_nullable => {},
|
|
type => '<=',
|
|
),
|
|
{
|
|
scols => [qw(a a d)],
|
|
slice => [0, 0, 3],
|
|
where => '((`a` < ?) OR (`a` = ? AND `d` <= ?))',
|
|
},
|
|
'WHERE for <=',
|
|
);
|
|
|
|
is_deeply(
|
|
$n->generate_cmp_where(
|
|
cols => [qw(a b c d)],
|
|
slice => [0, 3],
|
|
is_nullable => {},
|
|
type => '<',
|
|
),
|
|
{
|
|
scols => [qw(a a d)],
|
|
slice => [0, 0, 3],
|
|
where => '((`a` < ?) OR (`a` = ? AND `d` < ?))',
|
|
},
|
|
'WHERE for <',
|
|
);
|
|
|
|
|
|
# #############################################################################
|
|
# Done.
|
|
# #############################################################################
|
|
exit;
|